diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 0ae73e9825c8..684b06a36329 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" +#include "third_party/WebKit/public/web/WebCache.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebInputEvent.h" @@ -384,4 +385,30 @@ v8::Local MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags) { return mate::ConvertToV8(isolate, dict); } +v8::Local Converter::ToV8( + v8::Isolate* isolate, + const blink::WebCache::ResourceTypeStat& stat) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("count", static_cast(stat.count)); + dict.Set("size", static_cast(stat.size)); + dict.Set("liveSize", static_cast(stat.liveSize)); + dict.Set("decodedSize", static_cast(stat.decodedSize)); + dict.Set("purgedSize", static_cast(stat.purgedSize)); + dict.Set("purgeableSize", static_cast(stat.purgeableSize)); + return dict.GetHandle(); +} + +v8::Local Converter::ToV8( + v8::Isolate* isolate, + const blink::WebCache::ResourceTypeStats& stats) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("images", stats.images); + dict.Set("scripts", stats.scripts); + dict.Set("cssStyleSheets", stats.cssStyleSheets); + dict.Set("xslStyleSheets", stats.xslStyleSheets); + dict.Set("fonts", stats.fonts); + dict.Set("other", stats.other); + return dict.GetHandle(); +} + } // namespace mate diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index 514c6ab680c7..78275ab62ec9 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,6 +6,7 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" +#include "third_party/WebKit/public/web/WebCache.h" #include "third_party/WebKit/public/web/WebContextMenuData.h" namespace blink { @@ -100,8 +101,21 @@ struct Converter { const blink::WebContextMenuData::InputFieldType& in); }; -v8::Local EditFlagsToV8(v8::Isolate* isolate, int editFlags); +template<> +struct Converter { + static v8::Local ToV8( + v8::Isolate* isolate, + const blink::WebCache::ResourceTypeStat& stat); +}; +template<> +struct Converter { + static v8::Local ToV8( + v8::Isolate* isolate, + const blink::WebCache::ResourceTypeStats& stats); +}; + +v8::Local EditFlagsToV8(v8::Isolate* isolate, int editFlags); v8::Local MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags); } // namespace mate diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 0eebc94fc141..d32b5f1c8c46 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -5,14 +5,17 @@ #include "atom/renderer/api/atom_api_web_frame.h" #include "atom/common/api/event_emitter_caller.h" +#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" +#include "base/memory/memory_pressure_listener.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" +#include "third_party/WebKit/public/web/WebCache.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" @@ -168,6 +171,20 @@ mate::Handle WebFrame::Create(v8::Isolate* isolate) { return mate::CreateHandle(isolate, new WebFrame(isolate)); } +blink::WebCache::ResourceTypeStats WebFrame::GetResourceUsage( + v8::Isolate* isolate) { + blink::WebCache::ResourceTypeStats stats; + blink::WebCache::getResourceTypeStats(&stats); + return stats; +} + +void WebFrame::ClearCache(v8::Isolate* isolate) { + isolate->IdleNotificationDeadline(0.5); + blink::WebCache::clear(); + base::MemoryPressureListener::NotifyMemoryPressure( + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL); +} + // static void WebFrame::BuildPrototype( v8::Isolate* isolate, v8::Local prototype) { @@ -191,7 +208,9 @@ void WebFrame::BuildPrototype( .SetMethod("registerURLSchemeAsPrivileged", &WebFrame::RegisterURLSchemeAsPrivileged) .SetMethod("insertText", &WebFrame::InsertText) - .SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript); + .SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript) + .SetMethod("getResourceUsage", &WebFrame::GetResourceUsage) + .SetMethod("clearCache", &WebFrame::ClearCache); } } // namespace api diff --git a/atom/renderer/api/atom_api_web_frame.h b/atom/renderer/api/atom_api_web_frame.h index e1eeb224930b..2e120ecb6ae3 100644 --- a/atom/renderer/api/atom_api_web_frame.h +++ b/atom/renderer/api/atom_api_web_frame.h @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "native_mate/handle.h" #include "native_mate/wrappable.h" +#include "third_party/WebKit/public/web/WebCache.h" namespace blink { class WebLocalFrame; @@ -69,6 +70,10 @@ class WebFrame : public mate::Wrappable { // Excecuting scripts. void ExecuteJavaScript(const base::string16& code, mate::Arguments* args); + // Resource related methods + blink::WebCache::ResourceTypeStats GetResourceUsage(v8::Isolate* isolate); + void ClearCache(v8::Isolate* isolate); + scoped_ptr spell_check_client_; blink::WebLocalFrame* web_frame_; diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index de5a21db3db9..a933b8b48138 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -106,4 +106,43 @@ In the browser window some HTML APIs like `requestFullScreen` can only be invoked by a gesture from the user. Setting `userGesture` to `true` will remove this limitation. +### `webFrame.getResourceUsage()` + +Returns an object describing usage information of Blink's internal memory +caches. + +```javascript +console.log(webFrame.getResourceUsage()) +``` + +This will generate: + +```javascript +{ + images: { + count: 22, + size: 2549, + liveSize: 2542, + decodedSize: 478, + purgedSize: 0, + purgeableSize: 0 + }, + cssStyleSheets: { /* same with "images" */ }, + xslStyleSheets: { /* same with "images" */ }, + fonts: { /* same with "images" */ }, + other: { /* same with "images" */ }, +} +``` + +### `webFrame.clearCache()` + +Attempts to free memory that is no longer being used (like images from a +previous navigation). + +Note that blindly calling this method probably makes Electron slower since it +will have to refill these emptied caches, you should only call it if an event +in your app has occured that makes you think your page is actually using less +memory (i.e. you have navigated from a super heavy page to a mostly empty one, +and intend to stay there). + [spellchecker]: https://github.com/atom/node-spellchecker diff --git a/script/bootstrap.py b/script/bootstrap.py index 816a6182b201..df1a5792070b 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -52,9 +52,6 @@ def main(): if PLATFORM != 'win32': # Download prebuilt clang binaries. update_clang() - if not args.disable_clang and args.clang_dir == '': - # Build with prebuilt clang. - set_clang_env(os.environ) setup_python_libs() update_node_modules('.') @@ -67,7 +64,7 @@ def main(): create_chrome_version_h() touch_config_gypi() - run_update(defines) + run_update(defines, args.disable_clang, args.clang_dir) update_electron_modules('spec', args.target_arch) @@ -250,9 +247,14 @@ def touch_config_gypi(): f.write(content) -def run_update(defines): +def run_update(defines, disable_clang, clang_dir): + env = os.environ.copy() + if not disable_clang and clang_dir == '': + # Build with prebuilt clang. + set_clang_env(env) + update = os.path.join(SOURCE_ROOT, 'script', 'update.py') - execute_stdout([sys.executable, update, '--defines', defines]) + execute_stdout([sys.executable, update, '--defines', defines], env) if __name__ == '__main__':