Update from https://crrev.com/329939

Includes an update to build_v8.patch. https://crrev.com/329939 includes
mac->android cross compilation fixes.

TBR=cstout@chromium.org

Review URL: https://codereview.chromium.org/1141793003
diff --git a/base/BUILD.gn b/base/BUILD.gn
index e7985ef..2170520 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -216,6 +216,8 @@
     "files/file_posix.cc",
     "files/file_proxy.cc",
     "files/file_proxy.h",
+    "files/file_tracing.cc",
+    "files/file_tracing.h",
     "files/file_util.cc",
     "files/file_util.h",
     "files/file_util_android.cc",
@@ -269,6 +271,8 @@
     "mac/bundle_locations.h",
     "mac/bundle_locations.mm",
     "mac/cocoa_protocols.h",
+    "mac/dispatch_source_mach.cc",
+    "mac/dispatch_source_mach.h",
     "mac/foundation_util.h",
     "mac/foundation_util.mm",
     "mac/launch_services_util.cc",
@@ -599,6 +603,8 @@
     "win/iat_patch_function.h",
     "win/iunknown_impl.cc",
     "win/iunknown_impl.h",
+    "win/memory_pressure_monitor.cc",
+    "win/memory_pressure_monitor.h",
     "win/message_window.cc",
     "win/message_window.h",
     "win/metro.cc",
@@ -1146,6 +1152,7 @@
     "lazy_instance_unittest.cc",
     "logging_unittest.cc",
     "mac/bind_objc_block_unittest.mm",
+    "mac/dispatch_source_mach_unittest.cc",
     "mac/foundation_util_unittest.mm",
     "mac/libdispatch_task_runner_unittest.cc",
     "mac/mac_util_unittest.mm",
@@ -1282,6 +1289,7 @@
     "win/event_trace_provider_unittest.cc",
     "win/i18n_unittest.cc",
     "win/iunknown_impl_unittest.cc",
+    "win/memory_pressure_monitor_unittest.cc",
     "win/message_window_unittest.cc",
     "win/object_watcher_unittest.cc",
     "win/pe_image_unittest.cc",
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
index 11202a0..4d3cd55 100644
--- a/base/android/build_info.cc
+++ b/base/android/build_info.cc
@@ -68,11 +68,16 @@
   return Singleton<BuildInfo, BuildInfoSingletonTraits >::get();
 }
 
-void BuildInfo::set_java_exception_info(const std::string& info) {
+void BuildInfo::SetJavaExceptionInfo(const std::string& info) {
   DCHECK(!java_exception_info_) << "info should be set only once.";
   java_exception_info_ = strndup(info.c_str(), 4096);
 }
 
+void BuildInfo::ClearJavaExceptionInfo() {
+  delete java_exception_info_;
+  java_exception_info_ = nullptr;
+}
+
 // static
 bool BuildInfo::RegisterBindings(JNIEnv* env) {
   return RegisterNativesImpl(env);
diff --git a/base/android/build_info.h b/base/android/build_info.h
index 9d73bdb..d6155b9 100644
--- a/base/android/build_info.h
+++ b/base/android/build_info.h
@@ -99,7 +99,9 @@
     return java_exception_info_;
   }
 
-  void set_java_exception_info(const std::string& info);
+  void SetJavaExceptionInfo(const std::string& info);
+
+  void ClearJavaExceptionInfo();
 
   static bool RegisterBindings(JNIEnv* env);
 
diff --git a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
index 3df7b92..76d7396 100644
--- a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
+++ b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
@@ -349,6 +349,7 @@
 
     /**
      * @see android.view.Window#setStatusBarColor(int color).
+     * TODO(ianwen): remove this method after downstream rolling.
      */
     public static void setStatusBarColor(Activity activity, int statusBarColor) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
@@ -365,6 +366,22 @@
     }
 
     /**
+     * @see android.view.Window#setStatusBarColor(int color).
+     */
+    public static void setStatusBarColor(Window window, int statusBarColor) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            // If both system bars are black, we can remove these from our layout,
+            // removing or shrinking the SurfaceFlinger overlay required for our views.
+            if (statusBarColor == Color.BLACK && window.getNavigationBarColor() == Color.BLACK) {
+                window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            } else {
+                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            }
+            window.setStatusBarColor(statusBarColor);
+        }
+    }
+
+    /**
      * @see android.content.res.Resources#getDrawable(int id).
      */
     @SuppressWarnings("deprecation")
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java
index 0b3ed20..e46fc30 100644
--- a/base/android/java/src/org/chromium/base/PathUtils.java
+++ b/base/android/java/src/org/chromium/base/PathUtils.java
@@ -47,7 +47,7 @@
                 }
                 return paths;
             }
-        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, suffix);
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, suffix);
     }
 
     /**
diff --git a/base/android/java_runtime.h b/base/android/java_runtime.h
index bde4c5c..4ca889e 100644
--- a/base/android/java_runtime.h
+++ b/base/android/java_runtime.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_ANDROID_JAVA_RUNTIME_H
-#define BASE_ANDROID_JAVA_RUNTIME_H
+#ifndef BASE_ANDROID_JAVA_RUNTIME_H_
+#define BASE_ANDROID_JAVA_RUNTIME_H_
 
 #include "base/android/scoped_java_ref.h"
 #include "base/base_export.h"
@@ -25,4 +25,4 @@
 }  // namespace android
 }  // namespace base
 
-#endif  // BASE_ANDROID_JAVA_RUNTIME_H
+#endif  // BASE_ANDROID_JAVA_RUNTIME_H_
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 1b715dc..5416be3 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -28,52 +28,6 @@
     g_class_loader = LAZY_INSTANCE_INITIALIZER;
 jmethodID g_class_loader_load_class_method_id = 0;
 
-std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
-  ScopedJavaLocalRef<jclass> throwable_clazz =
-      GetClass(env, "java/lang/Throwable");
-  jmethodID throwable_printstacktrace =
-      MethodID::Get<MethodID::TYPE_INSTANCE>(
-          env, throwable_clazz.obj(), "printStackTrace",
-          "(Ljava/io/PrintStream;)V");
-
-  // Create an instance of ByteArrayOutputStream.
-  ScopedJavaLocalRef<jclass> bytearray_output_stream_clazz =
-      GetClass(env, "java/io/ByteArrayOutputStream");
-  jmethodID bytearray_output_stream_constructor =
-      MethodID::Get<MethodID::TYPE_INSTANCE>(
-          env, bytearray_output_stream_clazz.obj(), "<init>", "()V");
-  jmethodID bytearray_output_stream_tostring =
-      MethodID::Get<MethodID::TYPE_INSTANCE>(
-          env, bytearray_output_stream_clazz.obj(), "toString",
-          "()Ljava/lang/String;");
-  ScopedJavaLocalRef<jobject> bytearray_output_stream(env,
-      env->NewObject(bytearray_output_stream_clazz.obj(),
-                     bytearray_output_stream_constructor));
-
-  // Create an instance of PrintStream.
-  ScopedJavaLocalRef<jclass> printstream_clazz =
-      GetClass(env, "java/io/PrintStream");
-  jmethodID printstream_constructor =
-      MethodID::Get<MethodID::TYPE_INSTANCE>(
-          env, printstream_clazz.obj(), "<init>",
-          "(Ljava/io/OutputStream;)V");
-  ScopedJavaLocalRef<jobject> printstream(env,
-      env->NewObject(printstream_clazz.obj(), printstream_constructor,
-                     bytearray_output_stream.obj()));
-
-  // Call Throwable.printStackTrace(PrintStream)
-  env->CallVoidMethod(java_throwable, throwable_printstacktrace,
-      printstream.obj());
-
-  // Call ByteArrayOutputStream.toString()
-  ScopedJavaLocalRef<jstring> exception_string(
-      env, static_cast<jstring>(
-          env->CallObjectMethod(bytearray_output_stream.obj(),
-                                bytearray_output_stream_tostring)));
-
-  return ConvertJavaStringToUTF8(exception_string);
-}
-
 }  // namespace
 
 namespace base {
@@ -287,7 +241,7 @@
 
     // Set the exception_string in BuildInfo so that breakpad can read it.
     // RVO should avoid any extra copies of the exception string.
-    base::android::BuildInfo::GetInstance()->set_java_exception_info(
+    base::android::BuildInfo::GetInstance()->SetJavaExceptionInfo(
         GetJavaExceptionInfo(env, java_throwable));
   }
 
@@ -295,5 +249,52 @@
   CHECK(false) << "Please include Java exception stack in crash report";
 }
 
+std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
+  ScopedJavaLocalRef<jclass> throwable_clazz =
+      GetClass(env, "java/lang/Throwable");
+  jmethodID throwable_printstacktrace =
+      MethodID::Get<MethodID::TYPE_INSTANCE>(
+          env, throwable_clazz.obj(), "printStackTrace",
+          "(Ljava/io/PrintStream;)V");
+
+  // Create an instance of ByteArrayOutputStream.
+  ScopedJavaLocalRef<jclass> bytearray_output_stream_clazz =
+      GetClass(env, "java/io/ByteArrayOutputStream");
+  jmethodID bytearray_output_stream_constructor =
+      MethodID::Get<MethodID::TYPE_INSTANCE>(
+          env, bytearray_output_stream_clazz.obj(), "<init>", "()V");
+  jmethodID bytearray_output_stream_tostring =
+      MethodID::Get<MethodID::TYPE_INSTANCE>(
+          env, bytearray_output_stream_clazz.obj(), "toString",
+          "()Ljava/lang/String;");
+  ScopedJavaLocalRef<jobject> bytearray_output_stream(env,
+      env->NewObject(bytearray_output_stream_clazz.obj(),
+                     bytearray_output_stream_constructor));
+
+  // Create an instance of PrintStream.
+  ScopedJavaLocalRef<jclass> printstream_clazz =
+      GetClass(env, "java/io/PrintStream");
+  jmethodID printstream_constructor =
+      MethodID::Get<MethodID::TYPE_INSTANCE>(
+          env, printstream_clazz.obj(), "<init>",
+          "(Ljava/io/OutputStream;)V");
+  ScopedJavaLocalRef<jobject> printstream(env,
+      env->NewObject(printstream_clazz.obj(), printstream_constructor,
+                     bytearray_output_stream.obj()));
+
+  // Call Throwable.printStackTrace(PrintStream)
+  env->CallVoidMethod(java_throwable, throwable_printstacktrace,
+      printstream.obj());
+
+  // Call ByteArrayOutputStream.toString()
+  ScopedJavaLocalRef<jstring> exception_string(
+      env, static_cast<jstring>(
+          env->CallObjectMethod(bytearray_output_stream.obj(),
+                                bytearray_output_stream_tostring)));
+
+  return ConvertJavaStringToUTF8(exception_string);
+}
+
+
 }  // namespace android
 }  // namespace base
diff --git a/base/android/jni_android.h b/base/android/jni_android.h
index 504eb85..9df9041 100644
--- a/base/android/jni_android.h
+++ b/base/android/jni_android.h
@@ -130,6 +130,10 @@
 // This function will call CHECK() macro if there's any pending exception.
 BASE_EXPORT void CheckException(JNIEnv* env);
 
+// This returns a string representation of the java stack trace.
+BASE_EXPORT std::string GetJavaExceptionInfo(JNIEnv* env,
+                                             jthrowable java_throwable);
+
 }  // namespace android
 }  // namespace base
 
diff --git a/base/barrier_closure.cc b/base/barrier_closure.cc
index 1b77429..1dcc502 100644
--- a/base/barrier_closure.cc
+++ b/base/barrier_closure.cc
@@ -28,8 +28,9 @@
 void BarrierInfo::Run() {
   DCHECK(!base::AtomicRefCountIsZero(&num_callbacks_left_));
   if (!base::AtomicRefCountDec(&num_callbacks_left_)) {
-    done_closure_.Run();
+    base::Closure done_closure = done_closure_;
     done_closure_.Reset();
+    done_closure.Run();
   }
 }
 
diff --git a/base/barrier_closure_unittest.cc b/base/barrier_closure_unittest.cc
index ab05cb8..dcea09f 100644
--- a/base/barrier_closure_unittest.cc
+++ b/base/barrier_closure_unittest.cc
@@ -13,24 +13,68 @@
 
 TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
   int count = 0;
-  base::Closure doneClosure(base::Bind(&Increment, base::Unretained(&count)));
+  base::Closure done_closure(base::Bind(&Increment, base::Unretained(&count)));
 
-  base::Closure barrierClosure = base::BarrierClosure(0, doneClosure);
+  base::Closure barrier_closure = base::BarrierClosure(0, done_closure);
   EXPECT_EQ(1, count);
 }
 
 TEST(BarrierClosureTest, RunAfterNumClosures) {
   int count = 0;
-  base::Closure doneClosure(base::Bind(&Increment, base::Unretained(&count)));
+  base::Closure done_closure(base::Bind(&Increment, base::Unretained(&count)));
 
-  base::Closure barrierClosure = base::BarrierClosure(2, doneClosure);
+  base::Closure barrier_closure = base::BarrierClosure(2, done_closure);
   EXPECT_EQ(0, count);
 
-  barrierClosure.Run();
+  barrier_closure.Run();
   EXPECT_EQ(0, count);
 
-  barrierClosure.Run();
+  barrier_closure.Run();
   EXPECT_EQ(1, count);
 }
 
+class DestructionIndicator {
+ public:
+  // Sets |*destructed| to true in destructor.
+  DestructionIndicator(bool* destructed) : destructed_(destructed) {
+    *destructed_ = false;
+  }
+
+  ~DestructionIndicator() { *destructed_ = true; }
+
+  void DoNothing() {}
+
+ private:
+  bool* destructed_;
+};
+
+TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
+  bool done_destructed = false;
+  base::Closure barrier_closure = base::BarrierClosure(
+      1, base::Bind(&DestructionIndicator::DoNothing,
+                    base::Owned(new DestructionIndicator(&done_destructed))));
+  EXPECT_FALSE(done_destructed);
+  barrier_closure.Run();
+  EXPECT_TRUE(done_destructed);
+}
+
+void ResetBarrierClosure(base::Closure* closure) {
+  *closure = base::Closure();
+}
+
+// Tests a case when |done_closure| resets a |barrier_closure|.
+// |barrier_closure| is a Closure holding the |done_closure|. |done_closure|
+// holds a pointer back to the |barrier_closure|. When |barrier_closure| is
+// Run() it calls ResetBarrierClosure() which erases the |barrier_closure| while
+// still inside of its Run(). The Run() implementation (in base::BarrierClosure)
+// must not try use itself after executing ResetBarrierClosure() or this test
+// would crash inside Run().
+TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
+  base::Closure barrier_closure;
+  base::Closure done_closure =
+      base::Bind(ResetBarrierClosure, &barrier_closure);
+  barrier_closure = base::BarrierClosure(1, done_closure);
+  barrier_closure.Run();
+}
+
 }  // namespace
diff --git a/base/base.gyp b/base/base.gyp
index 80c3f10..05ff45e 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -514,6 +514,7 @@
         'lazy_instance_unittest.cc',
         'logging_unittest.cc',
         'mac/bind_objc_block_unittest.mm',
+        'mac/dispatch_source_mach_unittest.cc',
         'mac/foundation_util_unittest.mm',
         'mac/libdispatch_task_runner_unittest.cc',
         'mac/mac_util_unittest.mm',
@@ -654,6 +655,7 @@
         'win/event_trace_provider_unittest.cc',
         'win/i18n_unittest.cc',
         'win/iunknown_impl_unittest.cc',
+        'win/memory_pressure_monitor_unittest.cc',
         'win/message_window_unittest.cc',
         'win/object_watcher_unittest.cc',
         'win/pe_image_unittest.cc',
diff --git a/base/base.gypi b/base/base.gypi
index 4a8cd17..05ad049 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -209,6 +209,8 @@
           'files/file_posix.cc',
           'files/file_proxy.cc',
           'files/file_proxy.h',
+          'files/file_tracing.cc',
+          'files/file_tracing.h',
           'files/file_util.cc',
           'files/file_util.h',
           'files/file_util_android.cc',
@@ -278,6 +280,8 @@
           'mac/bundle_locations.mm',
           'mac/close_nocancel.cc',
           'mac/cocoa_protocols.h',
+          'mac/dispatch_source_mach.cc',
+          'mac/dispatch_source_mach.h',
           'mac/foundation_util.h',
           'mac/foundation_util.mm',
           'mac/launch_services_util.cc',
@@ -705,6 +709,8 @@
           'win/iat_patch_function.h',
           'win/iunknown_impl.cc',
           'win/iunknown_impl.h',
+          'win/memory_pressure_monitor.cc',
+          'win/memory_pressure_monitor.h',
           'win/message_window.cc',
           'win/message_window.h',
           'win/metro.cc',
diff --git a/base/base64.h b/base/base64.h
index def9b67..dd72c39 100644
--- a/base/base64.h
+++ b/base/base64.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_BASE64_H__
-#define BASE_BASE64_H__
+#ifndef BASE_BASE64_H_
+#define BASE_BASE64_H_
 
 #include <string>
 
@@ -22,4 +22,4 @@
 
 }  // namespace base
 
-#endif  // BASE_BASE64_H__
+#endif  // BASE_BASE64_H_
diff --git a/base/base_paths_win.h b/base/base_paths_win.h
index 4ab6af1..9ac9e45 100644
--- a/base/base_paths_win.h
+++ b/base/base_paths_win.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_BASE_PATHS_WIN_H__
-#define BASE_BASE_PATHS_WIN_H__
+#ifndef BASE_BASE_PATHS_WIN_H_
+#define BASE_BASE_PATHS_WIN_H_
 
 // This file declares windows-specific path keys for the base module.
 // These can be used with the PathService to access various special
@@ -51,4 +51,4 @@
 
 }  // namespace base
 
-#endif  // BASE_BASE_PATHS_WIN_H__
+#endif  // BASE_BASE_PATHS_WIN_H_
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 5fc1459..e053218 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -364,9 +364,10 @@
 struct BindState;
 
 template <typename Runnable,
-          typename R, typename... Args,
+          typename R,
+          typename... Args,
           typename... BoundArgs>
-struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>>
+struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> final
     : public BindStateBase {
  private:
   using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>;
@@ -398,14 +399,21 @@
   using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
 
   BindState(const Runnable& runnable, const BoundArgs&... bound_args)
-      : runnable_(runnable), ref_(bound_args...), bound_args_(bound_args...) {}
+      : BindStateBase(&Destroy),
+        runnable_(runnable),
+        ref_(bound_args...),
+        bound_args_(bound_args...) {}
 
   RunnableType runnable_;
   MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_;
   Tuple<BoundArgs...> bound_args_;
 
  private:
-  ~BindState() override {}
+  ~BindState() {}
+
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 
 }  // namespace internal
diff --git a/base/callback_internal.cc b/base/callback_internal.cc
index f360388..2553fe7 100644
--- a/base/callback_internal.cc
+++ b/base/callback_internal.cc
@@ -9,6 +9,15 @@
 namespace base {
 namespace internal {
 
+void BindStateBase::AddRef() {
+  AtomicRefCountInc(&ref_count_);
+}
+
+void BindStateBase::Release() {
+  if (!AtomicRefCountDec(&ref_count_))
+    destructor_(this);
+}
+
 CallbackBase::CallbackBase(const CallbackBase& c) = default;
 CallbackBase& CallbackBase::operator=(const CallbackBase& c) = default;
 
@@ -27,7 +36,7 @@
 CallbackBase::CallbackBase(BindStateBase* bind_state)
     : bind_state_(bind_state),
       polymorphic_invoke_(NULL) {
-  DCHECK(!bind_state_.get() || bind_state_->HasOneRef());
+  DCHECK(!bind_state_.get() || bind_state_->ref_count_ == 1);
 }
 
 CallbackBase::~CallbackBase() {
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 8a5c437..fefd7a2 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -10,15 +10,19 @@
 
 #include <stddef.h>
 
+#include "base/atomic_ref_count.h"
 #include "base/base_export.h"
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/template_util.h"
 
 template <typename T>
 class ScopedVector;
 
 namespace base {
 namespace internal {
+class CallbackBase;
 
 // BindStateBase is used to provide an opaque handle that the Callback
 // class can use to represent a function object with bound arguments.  It
@@ -26,10 +30,30 @@
 // DoInvoke function to perform the function execution.  This allows
 // us to shield the Callback class from the types of the bound argument via
 // "type erasure."
-class BindStateBase : public RefCountedThreadSafe<BindStateBase> {
+// At the base level, the only task is to add reference counting data. Don't use
+// RefCountedThreadSafe since it requires the destructor to be a virtual method.
+// Creating a vtable for every BindState template instantiation results in a lot
+// of bloat. Its only task is to call the destructor which can be done with a
+// function pointer.
+class BindStateBase {
  protected:
-  friend class RefCountedThreadSafe<BindStateBase>;
-  virtual ~BindStateBase() {}
+  explicit BindStateBase(void (*destructor)(BindStateBase*))
+      : ref_count_(0), destructor_(destructor) {}
+  ~BindStateBase() = default;
+
+ private:
+  friend class scoped_refptr<BindStateBase>;
+  friend class CallbackBase;
+
+  void AddRef();
+  void Release();
+
+  AtomicRefCount ref_count_;
+
+  // Pointer to a function that will properly destroy |this|.
+  void (*destructor_)(BindStateBase*);
+
+  DISALLOW_COPY_AND_ASSIGN(BindStateBase);
 };
 
 // Holds the Callback methods that don't require specialization to reduce
diff --git a/base/callback_unittest.cc b/base/callback_unittest.cc
index 5644b85..2844aa9 100644
--- a/base/callback_unittest.cc
+++ b/base/callback_unittest.cc
@@ -35,9 +35,13 @@
 struct BindState<void(void), void(void), void(FakeInvoker)>
     : public BindStateBase {
  public:
+  BindState() : BindStateBase(&Destroy) {}
   typedef FakeInvoker InvokerType;
  private:
-  ~BindState() override {}
+  ~BindState() {}
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 
 template <>
@@ -45,9 +49,13 @@
                            void(FakeInvoker, FakeInvoker)>
     : public BindStateBase {
  public:
+  BindState() : BindStateBase(&Destroy) {}
   typedef FakeInvoker InvokerType;
  private:
-  ~BindState() override {}
+  ~BindState() {}
+  static void Destroy(BindStateBase* self) {
+    delete static_cast<BindState*>(self);
+  }
 };
 }  // namespace internal
 
diff --git a/base/debug/profiler.h b/base/debug/profiler.h
index c50555e..2920d8a 100644
--- a/base/debug/profiler.h
+++ b/base/debug/profiler.h
@@ -87,4 +87,4 @@
 }  // namespace debug
 }  // namespace base
 
-#endif  // BASE_DEBUG_PROFILER_H__
+#endif  // BASE_DEBUG_PROFILER_H_
diff --git a/base/file_version_info.h b/base/file_version_info.h
index e18ba13..57b837c 100644
--- a/base/file_version_info.h
+++ b/base/file_version_info.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_FILE_VERSION_INFO_H__
-#define BASE_FILE_VERSION_INFO_H__
+#ifndef BASE_FILE_VERSION_INFO_H_
+#define BASE_FILE_VERSION_INFO_H_
 
 #include "build/build_config.h"
 
@@ -32,22 +32,21 @@
 // version returns values from the Info.plist as appropriate. TODO(avi): make
 // this a less-obvious Windows-ism.
 
-class FileVersionInfo {
+class BASE_EXPORT FileVersionInfo {
  public:
   virtual ~FileVersionInfo() {}
 #if defined(OS_WIN) || defined(OS_MACOSX)
   // Creates a FileVersionInfo for the specified path. Returns NULL if something
   // goes wrong (typically the file does not exit or cannot be opened). The
   // returned object should be deleted when you are done with it.
-  BASE_EXPORT static FileVersionInfo* CreateFileVersionInfo(
+  static FileVersionInfo* CreateFileVersionInfo(
       const base::FilePath& file_path);
 #endif  // OS_WIN || OS_MACOSX
 
 #if defined(OS_WIN)
   // Creates a FileVersionInfo for the specified module. Returns NULL in case
   // of error. The returned object should be deleted when you are done with it.
-  BASE_EXPORT static FileVersionInfo* CreateFileVersionInfoForModule(
-      HMODULE module);
+  static FileVersionInfo* CreateFileVersionInfoForModule(HMODULE module);
 
   // Creates a FileVersionInfo for the current module. Returns NULL in case
   // of error. The returned object should be deleted when you are done with it.
@@ -61,7 +60,7 @@
 #else
   // Creates a FileVersionInfo for the current module. Returns NULL in case
   // of error. The returned object should be deleted when you are done with it.
-  BASE_EXPORT static FileVersionInfo* CreateFileVersionInfoForCurrentModule();
+  static FileVersionInfo* CreateFileVersionInfoForCurrentModule();
 #endif  // OS_WIN
 
   // Accessors to the different version properties.
@@ -84,4 +83,4 @@
   virtual bool is_official_build() = 0;
 };
 
-#endif  // BASE_FILE_VERSION_INFO_H__
+#endif  // BASE_FILE_VERSION_INFO_H_
diff --git a/base/file_version_info_win.h b/base/file_version_info_win.h
index 92d0844..09d8d37 100644
--- a/base/file_version_info_win.h
+++ b/base/file_version_info_win.h
@@ -15,10 +15,10 @@
 struct tagVS_FIXEDFILEINFO;
 typedef tagVS_FIXEDFILEINFO VS_FIXEDFILEINFO;
 
-class FileVersionInfoWin : public FileVersionInfo {
+class BASE_EXPORT FileVersionInfoWin : public FileVersionInfo {
  public:
-  BASE_EXPORT FileVersionInfoWin(void* data, WORD language, WORD code_page);
-  BASE_EXPORT ~FileVersionInfoWin() override;
+  FileVersionInfoWin(void* data, WORD language, WORD code_page);
+  ~FileVersionInfoWin() override;
 
   // Accessors to the different version properties.
   // Returns an empty string if the property is not found.
@@ -40,11 +40,11 @@
   bool is_official_build() override;
 
   // Lets you access other properties not covered above.
-  BASE_EXPORT bool GetValue(const wchar_t* name, std::wstring* value);
+  bool GetValue(const wchar_t* name, std::wstring* value);
 
   // Similar to GetValue but returns a wstring (empty string if the property
   // does not exist).
-  BASE_EXPORT std::wstring GetStringValue(const wchar_t* name);
+  std::wstring GetStringValue(const wchar_t* name);
 
   // Get the fixed file info if it exists. Otherwise NULL
   VS_FIXEDFILEINFO* fixed_file_info() { return fixed_file_info_; }
diff --git a/base/files/dir_reader_linux.h b/base/files/dir_reader_linux.h
index cb0cbd3..abf2595 100644
--- a/base/files/dir_reader_linux.h
+++ b/base/files/dir_reader_linux.h
@@ -95,4 +95,4 @@
 
 }  // namespace base
 
-#endif // BASE_FILES_DIR_READER_LINUX_H_
+#endif  // BASE_FILES_DIR_READER_LINUX_H_
diff --git a/base/files/dir_reader_posix.h b/base/files/dir_reader_posix.h
index 6a20ced..6a32d9f 100644
--- a/base/files/dir_reader_posix.h
+++ b/base/files/dir_reader_posix.h
@@ -33,4 +33,4 @@
 
 }  // namespace base
 
-#endif // BASE_FILES_DIR_READER_POSIX_H_
+#endif  // BASE_FILES_DIR_READER_POSIX_H_
diff --git a/base/files/file.cc b/base/files/file.cc
index 8030bf1..58f80c5 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -4,6 +4,7 @@
 
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/files/file_tracing.h"
 #include "base/metrics/histogram.h"
 #include "base/timer/elapsed_timer.h"
 
@@ -25,11 +26,11 @@
 }
 
 #if !defined(OS_NACL)
-File::File(const FilePath& name, uint32 flags)
+File::File(const FilePath& path, uint32 flags)
     : error_details_(FILE_OK),
       created_(false),
       async_(false) {
-  Initialize(name, flags);
+  Initialize(path, flags);
 }
 #endif
 
@@ -51,6 +52,7 @@
 
 File::File(RValue other)
     : file_(other.object->TakePlatformFile()),
+      path_(other.object->path_),
       error_details_(other.object->error_details()),
       created_(other.object->created()),
       async_(other.object->async_) {
@@ -65,6 +67,7 @@
   if (this != other.object) {
     Close();
     SetPlatformFile(other.object->TakePlatformFile());
+    path_ = other.object->path_;
     error_details_ = other.object->error_details();
     created_ = other.object->created();
     async_ = other.object->async_;
@@ -73,12 +76,14 @@
 }
 
 #if !defined(OS_NACL)
-void File::Initialize(const FilePath& name, uint32 flags) {
-  if (name.ReferencesParent()) {
+void File::Initialize(const FilePath& path, uint32 flags) {
+  if (path.ReferencesParent()) {
     error_details_ = FILE_ERROR_ACCESS_DENIED;
     return;
   }
-  DoInitialize(name, flags);
+  path_ = path;
+  SCOPED_FILE_TRACE("Initialize");
+  DoInitialize(flags);
 }
 #endif
 
@@ -128,6 +133,7 @@
 
 bool File::Flush() {
   ElapsedTimer timer;
+  SCOPED_FILE_TRACE("Flush");
   bool return_value = DoFlush();
   UMA_HISTOGRAM_TIMES("PlatformFile.FlushTime", timer.Elapsed());
   return return_value;
diff --git a/base/files/file.h b/base/files/file.h
index 89077b4..b21b159 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -18,6 +18,8 @@
 
 #include "base/base_export.h"
 #include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/files/file_tracing.h"
 #include "base/files/scoped_file.h"
 #include "base/gtest_prod_util.h"
 #include "base/move.h"
@@ -31,8 +33,6 @@
 
 namespace base {
 
-class FilePath;
-
 #if defined(OS_WIN)
 typedef HANDLE PlatformFile;
 #elif defined(OS_POSIX)
@@ -162,8 +162,8 @@
   File();
 
   // Creates or opens the given file. This will fail with 'access denied' if the
-  // |name| contains path traversal ('..') components.
-  File(const FilePath& name, uint32 flags);
+  // |path| contains path traversal ('..') components.
+  File(const FilePath& path, uint32 flags);
 
   // Takes ownership of |platform_file|.
   explicit File(PlatformFile platform_file);
@@ -180,7 +180,7 @@
   File& operator=(RValue other);
 
   // Creates or opens the given file.
-  void Initialize(const FilePath& name, uint32 flags);
+  void Initialize(const FilePath& path, uint32 flags);
 
   bool IsValid() const;
 
@@ -191,7 +191,7 @@
 
   // Returns the OS result of opening this file. Note that the way to verify
   // the success of the operation is to use IsValid(), not this method:
-  //   File file(name, flags);
+  //   File file(path, flags);
   //   if (!file.IsValid())
   //     return;
   Error error_details() const { return error_details_; }
@@ -305,6 +305,8 @@
  private:
   FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption);
 
+  friend class FileTracing::ScopedTrace;
+
 #if defined(OS_POSIX)
   // Encloses a single ScopedFD, saving a cheap tamper resistent memory checksum
   // alongside it. This checksum is validated at every access, allowing early
@@ -350,9 +352,9 @@
   };
 #endif
 
-  // Creates or opens the given file. Only called if |name| has no traversal
-  // ('..') components.
-  void DoInitialize(const FilePath& name, uint32 flags);
+  // Creates or opens the given file. Only called if |path_| has no
+  // traversal ('..') components.
+  void DoInitialize(uint32 flags);
 
   // TODO(tnagel): Reintegrate into Flush() once histogram isn't needed anymore,
   // cf. issue 473337.
@@ -366,6 +368,12 @@
   MemoryCheckingScopedFD file_;
 #endif
 
+  // Path that |Initialize()| was called with. Only set if safe (i.e. no '..').
+  FilePath path_;
+
+  // Object tied to the lifetime of |this| that enables/disables tracing.
+  FileTracing::ScopedEnabler trace_enabler_;
+
   Error error_details_;
   bool created_;
   bool async_;
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 4c79057..bb49d2d 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -9,7 +9,6 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/posix/eintr_wrapper.h"
@@ -173,6 +172,7 @@
   if (!IsValid())
     return;
 
+  SCOPED_FILE_TRACE("Close");
   ThreadRestrictions::AssertIOAllowed();
   file_.reset();
 }
@@ -181,6 +181,8 @@
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Seek", offset);
+
 #if defined(OS_ANDROID)
   COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit);
   return lseek64(file_.get(), static_cast<off64_t>(offset),
@@ -198,6 +200,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Read", size);
+
   int bytes_read = 0;
   int rv;
   do {
@@ -218,6 +222,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("ReadAtCurrentPos", size);
+
   int bytes_read = 0;
   int rv;
   do {
@@ -234,7 +240,7 @@
 int File::ReadNoBestEffort(int64 offset, char* data, int size) {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
-
+  SCOPED_FILE_TRACE_WITH_SIZE("ReadNoBestEffort", size);
   return HANDLE_EINTR(pread(file_.get(), data, size, offset));
 }
 
@@ -244,6 +250,7 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("ReadAtCurrentPosNoBestEffort", size);
   return HANDLE_EINTR(read(file_.get(), data, size));
 }
 
@@ -257,6 +264,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Write", size);
+
   int bytes_written = 0;
   int rv;
   do {
@@ -277,6 +286,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("WriteAtCurrentPos", size);
+
   int bytes_written = 0;
   int rv;
   do {
@@ -297,12 +308,15 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("WriteAtCurrentPosNoBestEffort", size);
   return HANDLE_EINTR(write(file_.get(), data, size));
 }
 
 int64 File::GetLength() {
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE("GetLength");
+
   stat_wrapper_t file_info;
   if (CallFstat(file_.get(), &file_info))
     return false;
@@ -313,6 +327,8 @@
 bool File::SetLength(int64 length) {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
+
+  SCOPED_FILE_TRACE_WITH_SIZE("SetLength", length);
   return !CallFtruncate(file_.get(), length);
 }
 
@@ -320,6 +336,8 @@
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE("SetTimes");
+
   timeval times[2];
   times[0] = last_access_time.ToTimeVal();
   times[1] = last_modified_time.ToTimeVal();
@@ -330,6 +348,8 @@
 bool File::GetInfo(Info* info) {
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE("GetInfo");
+
   stat_wrapper_t file_info;
   if (CallFstat(file_.get(), &file_info))
     return false;
@@ -339,10 +359,12 @@
 }
 
 File::Error File::Lock() {
+  SCOPED_FILE_TRACE("Lock");
   return CallFctnlFlock(file_.get(), true);
 }
 
 File::Error File::Unlock() {
+  SCOPED_FILE_TRACE("Unlock");
   return CallFctnlFlock(file_.get(), false);
 }
 
@@ -350,6 +372,8 @@
   if (!IsValid())
     return File();
 
+  SCOPED_FILE_TRACE("Duplicate");
+
   PlatformFile other_fd = dup(GetPlatformFile());
   if (other_fd == -1)
     return File(OSErrorToFileError(errno));
@@ -442,7 +466,7 @@
 // NaCl doesn't implement system calls to open files directly.
 #if !defined(OS_NACL)
 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
-void File::DoInitialize(const FilePath& name, uint32 flags) {
+void File::DoInitialize(uint32 flags) {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(!IsValid());
 
@@ -497,7 +521,7 @@
   mode |= S_IRGRP | S_IROTH;
 #endif
 
-  int descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode));
+  int descriptor = HANDLE_EINTR(open(path_.value().c_str(), open_flags, mode));
 
   if (flags & FLAG_OPEN_ALWAYS) {
     if (descriptor < 0) {
@@ -505,7 +529,7 @@
       if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE)
         open_flags |= O_EXCL;   // together with O_CREAT implies O_NOFOLLOW
 
-      descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode));
+      descriptor = HANDLE_EINTR(open(path_.value().c_str(), open_flags, mode));
       if (descriptor >= 0)
         created_ = true;
     }
@@ -520,7 +544,7 @@
     created_ = true;
 
   if (flags & FLAG_DELETE_ON_CLOSE)
-    unlink(name.value().c_str());
+    unlink(path_.value().c_str());
 
   async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
   error_details_ = FILE_OK;
@@ -531,6 +555,7 @@
 bool File::DoFlush() {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
+
 #if defined(OS_NACL)
   NOTIMPLEMENTED();  // NaCl doesn't implement fsync.
   return true;
diff --git a/base/files/file_tracing.cc b/base/files/file_tracing.cc
new file mode 100644
index 0000000..a1919c4
--- /dev/null
+++ b/base/files/file_tracing.cc
@@ -0,0 +1,56 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/files/file_tracing.h"
+
+#include "base/files/file.h"
+
+namespace base {
+
+namespace {
+FileTracing::Provider* g_provider = nullptr;
+}
+
+// static
+void FileTracing::SetProvider(FileTracing::Provider* provider) {
+  g_provider = provider;
+}
+
+FileTracing::ScopedEnabler::ScopedEnabler() {
+  if (g_provider)
+    g_provider->FileTracingEnable(this);
+}
+
+FileTracing::ScopedEnabler::~ScopedEnabler() {
+  if (g_provider)
+    g_provider->FileTracingDisable(this);
+}
+
+FileTracing::ScopedTrace::ScopedTrace() : initialized_(false) {}
+
+FileTracing::ScopedTrace::~ScopedTrace() {
+  if (initialized_ && g_provider) {
+    g_provider->FileTracingEventEnd(
+        name_, &file_->trace_enabler_, file_->path_, size_);
+  }
+}
+
+bool FileTracing::ScopedTrace::ShouldInitialize() const {
+  return g_provider && g_provider->FileTracingCategoryIsEnabled();
+}
+
+void FileTracing::ScopedTrace::Initialize(
+    const char* name, File* file, int64 size) {
+  file_ = file;
+  name_ = name;
+  size_ = size;
+  initialized_ = true;
+
+  if (g_provider) {
+    g_provider->FileTracingEventBegin(
+        name_, &file_->trace_enabler_, file_->path_, size_);
+  }
+}
+
+}  // namespace base
diff --git a/base/files/file_tracing.h b/base/files/file_tracing.h
new file mode 100644
index 0000000..8452037
--- /dev/null
+++ b/base/files/file_tracing.h
@@ -0,0 +1,95 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_FILES_FILE_TRACING_H_
+#define BASE_FILES_FILE_TRACING_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/macros.h"
+
+#define FILE_TRACING_PREFIX "File"
+
+#define SCOPED_FILE_TRACE_WITH_SIZE(name, size) \
+    FileTracing::ScopedTrace scoped_file_trace; \
+    if (scoped_file_trace.ShouldInitialize()) \
+      scoped_file_trace.Initialize(FILE_TRACING_PREFIX "::" name, this, size)
+
+#define SCOPED_FILE_TRACE(name) SCOPED_FILE_TRACE_WITH_SIZE(name, 0)
+
+namespace base {
+
+class File;
+class FilePath;
+
+class BASE_EXPORT FileTracing {
+ public:
+  class Provider {
+   public:
+    // Whether the file tracing category is currently enabled.
+    virtual bool FileTracingCategoryIsEnabled() const = 0;
+
+    // Enables file tracing for |id|. Must be called before recording events.
+    virtual void FileTracingEnable(void* id) = 0;
+
+    // Disables file tracing for |id|.
+    virtual void FileTracingDisable(void* id) = 0;
+
+    // Begins an event for |id| with |name|. |path| tells where in the directory
+    // structure the event is happening (and may be blank). |size| is reported
+    // if not 0.
+    virtual void FileTracingEventBegin(
+        const char* name, void* id, const FilePath& path, int64 size) = 0;
+
+    // Ends an event for |id| with |name|. |path| tells where in the directory
+    // structure the event is happening (and may be blank). |size| is reported
+    // if not 0.
+    virtual void FileTracingEventEnd(
+        const char* name, void* id, const FilePath& path, int64 size) = 0;
+  };
+
+  // Sets a global file tracing provider to query categories and record events.
+  static void SetProvider(Provider* provider);
+
+  // Enables file tracing while in scope.
+  class ScopedEnabler {
+   public:
+    ScopedEnabler();
+    ~ScopedEnabler();
+  };
+
+  class ScopedTrace {
+   public:
+    ScopedTrace();
+    ~ScopedTrace();
+
+    // Whether this trace should be initialized or not.
+    bool ShouldInitialize() const;
+
+    // Called only if the tracing category is enabled.
+    void Initialize(const char* event, File* file, int64 size);
+
+   private:
+    // True if |Initialize()| has been called. Don't touch |path_|, |event_|,
+    // or |bytes_| if |initialized_| is false.
+    bool initialized_;
+
+    // The event name to trace (e.g. "Read", "Write"). Prefixed with "File".
+    const char* name_;
+
+    // The file being traced. Must outlive this class.
+    File* file_;
+
+    // The size (in bytes) of this trace. Not reported if 0.
+    int64 size_;
+
+    DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
+  };
+
+  DISALLOW_COPY_AND_ASSIGN(FileTracing);
+};
+
+}  // namespace base
+
+#endif  // BASE_FILES_FILE_TRACING_H_
diff --git a/base/files/file_win.cc b/base/files/file_win.cc
index 200ea29..9792852 100644
--- a/base/files/file_win.cc
+++ b/base/files/file_win.cc
@@ -6,7 +6,6 @@
 
 #include <io.h>
 
-#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/threading/thread_restrictions.h"
@@ -31,16 +30,20 @@
 }
 
 void File::Close() {
-  if (file_.IsValid()) {
-    ThreadRestrictions::AssertIOAllowed();
-    file_.Close();
-  }
+  if (!file_.IsValid())
+    return;
+
+  ThreadRestrictions::AssertIOAllowed();
+  SCOPED_FILE_TRACE("Close");
+  file_.Close();
 }
 
 int64 File::Seek(Whence whence, int64 offset) {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Seek", offset);
+
   LARGE_INTEGER distance, res;
   distance.QuadPart = offset;
   DWORD move_method = static_cast<DWORD>(whence);
@@ -56,6 +59,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Read", size);
+
   LARGE_INTEGER offset_li;
   offset_li.QuadPart = offset;
 
@@ -79,6 +84,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("ReadAtCurrentPos", size);
+
   DWORD bytes_read;
   if (::ReadFile(file_.Get(), data, size, &bytes_read, NULL))
     return bytes_read;
@@ -89,10 +96,12 @@
 }
 
 int File::ReadNoBestEffort(int64 offset, char* data, int size) {
+  // TODO(dbeam): trace this separately?
   return Read(offset, data, size);
 }
 
 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) {
+  // TODO(dbeam): trace this separately?
   return ReadAtCurrentPos(data, size);
 }
 
@@ -101,6 +110,8 @@
   DCHECK(IsValid());
   DCHECK(!async_);
 
+  SCOPED_FILE_TRACE_WITH_SIZE("Write", size);
+
   LARGE_INTEGER offset_li;
   offset_li.QuadPart = offset;
 
@@ -122,6 +133,8 @@
   if (size < 0)
     return -1;
 
+  SCOPED_FILE_TRACE_WITH_SIZE("WriteAtCurrentPos", size);
+
   DWORD bytes_written;
   if (::WriteFile(file_.Get(), data, size, &bytes_written, NULL))
     return bytes_written;
@@ -136,6 +149,9 @@
 int64 File::GetLength() {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
+
+  SCOPED_FILE_TRACE("GetLength");
+
   LARGE_INTEGER size;
   if (!::GetFileSizeEx(file_.Get(), &size))
     return -1;
@@ -147,6 +163,8 @@
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE_WITH_SIZE("SetLength", length);
+
   // Get the current file pointer.
   LARGE_INTEGER file_pointer;
   LARGE_INTEGER zero;
@@ -176,6 +194,8 @@
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE("SetTimes");
+
   FILETIME last_access_filetime = last_access_time.ToFileTime();
   FILETIME last_modified_filetime = last_modified_time.ToFileTime();
   return (::SetFileTime(file_.Get(), NULL, &last_access_filetime,
@@ -186,6 +206,8 @@
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(IsValid());
 
+  SCOPED_FILE_TRACE("GetInfo");
+
   BY_HANDLE_FILE_INFORMATION file_info;
   if (!GetFileInformationByHandle(file_.Get(), &file_info))
     return false;
@@ -205,6 +227,9 @@
 
 File::Error File::Lock() {
   DCHECK(IsValid());
+
+  SCOPED_FILE_TRACE("Lock");
+
   BOOL result = LockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD);
   if (!result)
     return OSErrorToFileError(GetLastError());
@@ -213,6 +238,9 @@
 
 File::Error File::Unlock() {
   DCHECK(IsValid());
+
+  SCOPED_FILE_TRACE("Unlock");
+
   BOOL result = UnlockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD);
   if (!result)
     return OSErrorToFileError(GetLastError());
@@ -223,6 +251,8 @@
   if (!IsValid())
     return File();
 
+  SCOPED_FILE_TRACE("Duplicate");
+
   HANDLE other_handle = nullptr;
 
   if (!::DuplicateHandle(GetCurrentProcess(),  // hSourceProcessHandle
@@ -278,7 +308,7 @@
   }
 }
 
-void File::DoInitialize(const FilePath& name, uint32 flags) {
+void File::DoInitialize(uint32 flags) {
   ThreadRestrictions::AssertIOAllowed();
   DCHECK(!IsValid());
 
@@ -346,7 +376,7 @@
   if (flags & FLAG_BACKUP_SEMANTICS)
     create_flags |= FILE_FLAG_BACKUP_SEMANTICS;
 
-  file_.Set(CreateFile(name.value().c_str(), access, sharing, NULL,
+  file_.Set(CreateFile(path_.value().c_str(), access, sharing, NULL,
                        disposition, create_flags, NULL));
 
   if (file_.IsValid()) {
diff --git a/base/format_macros.h b/base/format_macros.h
index 4d90c59..d58658d 100644
--- a/base/format_macros.h
+++ b/base/format_macros.h
@@ -23,19 +23,20 @@
 
 #include "build/build_config.h"
 
-#if defined(OS_POSIX)
-
-#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64)
+#if defined(OS_POSIX) && (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && \
+    !defined(PRId64)
 #error "inttypes.h has already been included before this header file, but "
 #error "without __STDC_FORMAT_MACROS defined."
 #endif
 
-#if !defined(__STDC_FORMAT_MACROS)
+#if defined(OS_POSIX) && !defined(__STDC_FORMAT_MACROS)
 #define __STDC_FORMAT_MACROS
 #endif
 
 #include <inttypes.h>
 
+#if defined(OS_POSIX)
+
 // GCC will concatenate wide and narrow strings correctly, so nothing needs to
 // be done here.
 #define WidePRId64 PRId64
@@ -76,16 +77,8 @@
 
 #else  // OS_WIN
 
-#if !defined(PRId64)
-#define PRId64 "I64d"
-#endif
-
-#if !defined(PRIu64)
-#define PRIu64 "I64u"
-#endif
-
-#if !defined(PRIx64)
-#define PRIx64 "I64x"
+#if !defined(PRId64) || !defined(PRIu64) || !defined(PRIx64)
+#error "inttypes.h provided by win toolchain should define these."
 #endif
 
 #define WidePRId64 L"I64d"
diff --git a/base/i18n/icu_string_conversions.cc b/base/i18n/icu_string_conversions.cc
index 1530117..edb31c3 100644
--- a/base/i18n/icu_string_conversions.cc
+++ b/base/i18n/icu_string_conversions.cc
@@ -134,14 +134,6 @@
   }
 }
 
-inline UConverterType utf32_platform_endian() {
-#if U_IS_BIG_ENDIAN
-  return UCNV_UTF32_BigEndian;
-#else
-  return UCNV_UTF32_LittleEndian;
-#endif
-}
-
 }  // namespace
 
 // Codepage <-> Wide/UTF-16  ---------------------------------------------------
@@ -197,74 +189,6 @@
   return true;
 }
 
-bool WideToCodepage(const std::wstring& wide,
-                    const char* codepage_name,
-                    OnStringConversionError::Type on_error,
-                    std::string* encoded) {
-#if defined(WCHAR_T_IS_UTF16)
-  return UTF16ToCodepage(wide, codepage_name, on_error, encoded);
-#elif defined(WCHAR_T_IS_UTF32)
-  encoded->clear();
-
-  UErrorCode status = U_ZERO_ERROR;
-  UConverter* converter = ucnv_open(codepage_name, &status);
-  if (!U_SUCCESS(status))
-    return false;
-
-  int utf16_len;
-  // When wchar_t is wider than UChar (16 bits), transform |wide| into a
-  // UChar* string.  Size the UChar* buffer to be large enough to hold twice
-  // as many UTF-16 code units (UChar's) as there are Unicode code points,
-  // in case each code points translates to a UTF-16 surrogate pair,
-  // and leave room for a NUL terminator.
-  std::vector<UChar> utf16(wide.length() * 2 + 1);
-  u_strFromUTF32(&utf16[0], utf16.size(), &utf16_len,
-                 reinterpret_cast<const UChar32*>(wide.c_str()),
-                 wide.length(), &status);
-  DCHECK(U_SUCCESS(status)) << "failed to convert wstring to UChar*";
-
-  return ConvertFromUTF16(converter, &utf16[0], utf16_len, on_error, encoded);
-#endif  // defined(WCHAR_T_IS_UTF32)
-}
-
-bool CodepageToWide(const std::string& encoded,
-                    const char* codepage_name,
-                    OnStringConversionError::Type on_error,
-                    std::wstring* wide) {
-#if defined(WCHAR_T_IS_UTF16)
-  return CodepageToUTF16(encoded, codepage_name, on_error, wide);
-#elif defined(WCHAR_T_IS_UTF32)
-  wide->clear();
-
-  UErrorCode status = U_ZERO_ERROR;
-  UConverter* converter = ucnv_open(codepage_name, &status);
-  if (!U_SUCCESS(status))
-    return false;
-
-  // The maximum length in 4 byte unit of UTF-32 output would be
-  // at most the same as the number of bytes in input. In the worst
-  // case of GB18030 (excluding escaped-based encodings like ISO-2022-JP),
-  // this can be 4 times larger than actually needed.
-  size_t wchar_max_length = encoded.length() + 1;
-
-  SetUpErrorHandlerForToUChars(on_error, converter, &status);
-  scoped_ptr<wchar_t[]> buffer(new wchar_t[wchar_max_length]);
-  int actual_size = ucnv_toAlgorithmic(utf32_platform_endian(), converter,
-      reinterpret_cast<char*>(buffer.get()),
-      static_cast<int>(wchar_max_length) * sizeof(wchar_t), encoded.data(),
-      static_cast<int>(encoded.length()), &status);
-  ucnv_close(converter);
-  if (!U_SUCCESS(status)) {
-    wide->clear();  // Make sure the output is empty on error.
-    return false;
-  }
-
-  // actual_size is # of bytes.
-  wide->assign(buffer.get(), actual_size / sizeof(wchar_t));
-  return true;
-#endif  // defined(WCHAR_T_IS_UTF32)
-}
-
 bool ConvertToUtf8AndNormalize(const std::string& text,
                                const std::string& charset,
                                std::string* result) {
diff --git a/base/i18n/icu_string_conversions.h b/base/i18n/icu_string_conversions.h
index fd2ae46..9135da8 100644
--- a/base/i18n/icu_string_conversions.h
+++ b/base/i18n/icu_string_conversions.h
@@ -13,8 +13,7 @@
 
 namespace base {
 
-// Defines the error handling modes of UTF16ToCodepage, CodepageToUTF16,
-// WideToCodepage and CodepageToWide.
+// Defines the error handling modes of UTF16ToCodepage and CodepageToUTF16.
 class OnStringConversionError {
  public:
   enum Type {
@@ -47,18 +46,6 @@
                                       OnStringConversionError::Type on_error,
                                       string16* utf16);
 
-// Converts between wide strings and the encoding specified.  If the
-// encoding doesn't exist or the encoding fails (when on_error is FAIL),
-// returns false.
-BASE_I18N_EXPORT bool WideToCodepage(const std::wstring& wide,
-                                     const char* codepage_name,
-                                     OnStringConversionError::Type on_error,
-                                     std::string* encoded);
-BASE_I18N_EXPORT bool CodepageToWide(const std::string& encoded,
-                                     const char* codepage_name,
-                                     OnStringConversionError::Type on_error,
-                                     std::wstring* wide);
-
 // Converts from any codepage to UTF-8 and ensures the resulting UTF-8 is
 // normalized.
 BASE_I18N_EXPORT bool ConvertToUtf8AndNormalize(const std::string& text,
diff --git a/base/i18n/icu_string_conversions_unittest.cc b/base/i18n/icu_string_conversions_unittest.cc
index d4d3251..821529d 100644
--- a/base/i18n/icu_string_conversions_unittest.cc
+++ b/base/i18n/icu_string_conversions_unittest.cc
@@ -42,49 +42,8 @@
 #endif
 }
 
-const wchar_t* const kConvertRoundtripCases[] = {
-  L"Google Video",
-  // "网页 图片 资讯更多 »"
-  L"\x7f51\x9875\x0020\x56fe\x7247\x0020\x8d44\x8baf\x66f4\x591a\x0020\x00bb",
-  //  "Παγκόσμιος Ιστός"
-  L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9"
-  L"\x03bf\x03c2\x0020\x0399\x03c3\x03c4\x03cc\x03c2",
-  // "Поиск страниц на русском"
-  L"\x041f\x043e\x0438\x0441\x043a\x0020\x0441\x0442"
-  L"\x0440\x0430\x043d\x0438\x0446\x0020\x043d\x0430"
-  L"\x0020\x0440\x0443\x0441\x0441\x043a\x043e\x043c",
-  // "전체서비스"
-  L"\xc804\xccb4\xc11c\xbe44\xc2a4",
-
-  // Test characters that take more than 16 bits. This will depend on whether
-  // wchar_t is 16 or 32 bits.
-#if defined(WCHAR_T_IS_UTF16)
-  L"\xd800\xdf00",
-  // ?????  (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E)
-  L"\xd807\xdd40\xd807\xdd41\xd807\xdd42\xd807\xdd43\xd807\xdd44",
-#elif defined(WCHAR_T_IS_UTF32)
-  L"\x10300",
-  // ?????  (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E)
-  L"\x11d40\x11d41\x11d42\x11d43\x11d44",
-#endif
-};
-
 }  // namespace
 
-TEST(ICUStringConversionsTest, ConvertCodepageUTF8) {
-  // Make sure WideToCodepage works like WideToUTF8.
-  for (size_t i = 0; i < arraysize(kConvertRoundtripCases); ++i) {
-    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %ls",
-                                    i, kConvertRoundtripCases[i]));
-
-    std::string expected(WideToUTF8(kConvertRoundtripCases[i]));
-    std::string utf8;
-    EXPECT_TRUE(WideToCodepage(kConvertRoundtripCases[i], kCodepageUTF8,
-                               OnStringConversionError::SKIP, &utf8));
-    EXPECT_EQ(expected, utf8);
-  }
-}
-
 // kConverterCodepageCases is not comprehensive. There are a number of cases
 // to add if we really want to have a comprehensive coverage of various
 // codepages and their 'idiosyncrasies'. Currently, the only implementation
@@ -233,73 +192,6 @@
    NULL},
 };
 
-TEST(ICUStringConversionsTest, ConvertBetweenCodepageAndWide) {
-  for (size_t i = 0; i < arraysize(kConvertCodepageCases); ++i) {
-    SCOPED_TRACE(base::StringPrintf(
-                     "Test[%" PRIuS "]: <encoded: %s> <codepage: %s>", i,
-                     kConvertCodepageCases[i].encoded,
-                     kConvertCodepageCases[i].codepage_name));
-
-    std::wstring wide;
-    bool success = CodepageToWide(kConvertCodepageCases[i].encoded,
-                                  kConvertCodepageCases[i].codepage_name,
-                                  kConvertCodepageCases[i].on_error,
-                                  &wide);
-    EXPECT_EQ(kConvertCodepageCases[i].success, success);
-    EXPECT_EQ(kConvertCodepageCases[i].wide, wide);
-
-    // When decoding was successful and nothing was skipped, we also check the
-    // reverse conversion. Not all conversions are round-trippable, but
-    // kConverterCodepageCases does not have any one-way conversion at the
-    // moment.
-    if (success &&
-        kConvertCodepageCases[i].on_error ==
-            OnStringConversionError::FAIL) {
-      std::string encoded;
-      success = WideToCodepage(wide, kConvertCodepageCases[i].codepage_name,
-                               kConvertCodepageCases[i].on_error, &encoded);
-      EXPECT_EQ(kConvertCodepageCases[i].success, success);
-      EXPECT_EQ(kConvertCodepageCases[i].encoded, encoded);
-    }
-  }
-
-  // The above cases handled codepage->wide errors, but not wide->codepage.
-  // Test that here.
-  std::string encoded("Temp data");  // Make sure the string gets cleared.
-
-  // First test going to an encoding that can not represent that character.
-  EXPECT_FALSE(WideToCodepage(L"Chinese\xff27", "iso-8859-1",
-                              OnStringConversionError::FAIL, &encoded));
-  EXPECT_TRUE(encoded.empty());
-  EXPECT_TRUE(WideToCodepage(L"Chinese\xff27", "iso-8859-1",
-                             OnStringConversionError::SKIP, &encoded));
-  EXPECT_STREQ("Chinese", encoded.c_str());
-  // From Unicode, SUBSTITUTE is the same as SKIP for now.
-  EXPECT_TRUE(WideToCodepage(L"Chinese\xff27", "iso-8859-1",
-                             OnStringConversionError::SUBSTITUTE,
-                             &encoded));
-  EXPECT_STREQ("Chinese", encoded.c_str());
-
-#if defined(WCHAR_T_IS_UTF16)
-  // When we're in UTF-16 mode, test an invalid UTF-16 character in the input.
-  EXPECT_FALSE(WideToCodepage(L"a\xd800z", "iso-8859-1",
-                              OnStringConversionError::FAIL, &encoded));
-  EXPECT_TRUE(encoded.empty());
-  EXPECT_TRUE(WideToCodepage(L"a\xd800z", "iso-8859-1",
-                             OnStringConversionError::SKIP, &encoded));
-  EXPECT_STREQ("az", encoded.c_str());
-#endif  // WCHAR_T_IS_UTF16
-
-  // Invalid characters should fail.
-  EXPECT_TRUE(WideToCodepage(L"a\xffffz", "iso-8859-1",
-                             OnStringConversionError::SKIP, &encoded));
-  EXPECT_STREQ("az", encoded.c_str());
-
-  // Invalid codepages should fail.
-  EXPECT_FALSE(WideToCodepage(L"Hello, world", "awesome-8571-2",
-                              OnStringConversionError::SKIP, &encoded));
-}
-
 TEST(ICUStringConversionsTest, ConvertBetweenCodepageAndUTF16) {
   for (size_t i = 0; i < arraysize(kConvertCodepageCases); ++i) {
     SCOPED_TRACE(base::StringPrintf(
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index ede6467..a9f0b12 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -59,10 +59,10 @@
 #endif
 }
 
-#if defined(OS_ANDROID)
+#if !defined(OS_NACL)
 bool InitializeICUWithFileDescriptor(
-    int data_fd,
-    base::MemoryMappedFile::Region data_region) {
+    PlatformFile data_fd,
+    MemoryMappedFile::Region data_region) {
 #if !defined(NDEBUG)
   DCHECK(!g_check_called_once || !g_called_once);
   g_called_once = true;
@@ -72,9 +72,9 @@
   // The ICU data is statically linked.
   return true;
 #elif (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
-  CR_DEFINE_STATIC_LOCAL(base::MemoryMappedFile, mapped_file, ());
+  CR_DEFINE_STATIC_LOCAL(MemoryMappedFile, mapped_file, ());
   if (!mapped_file.IsValid()) {
-    if (!mapped_file.Initialize(base::File(data_fd), data_region)) {
+    if (!mapped_file.Initialize(File(data_fd), data_region)) {
       LOG(ERROR) << "Couldn't mmap icu data file";
       return false;
     }
@@ -84,10 +84,8 @@
   return err == U_ZERO_ERROR;
 #endif // ICU_UTIL_DATA_FILE
 }
-#endif
 
 
-#if !defined(OS_NACL)
 bool InitializeICU() {
 #if !defined(NDEBUG)
   DCHECK(!g_check_called_once || !g_called_once);
@@ -98,7 +96,7 @@
 #if (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED)
   // We expect to find the ICU data module alongside the current module.
   FilePath data_path;
-  PathService::Get(base::DIR_MODULE, &data_path);
+  PathService::Get(DIR_MODULE, &data_path);
   data_path = data_path.AppendASCII(ICU_UTIL_DATA_SHARED_MODULE_NAME);
 
   HMODULE module = LoadLibrary(data_path.value().c_str());
@@ -128,24 +126,24 @@
 
   // Chrome doesn't normally shut down ICU, so the mapped data shouldn't ever
   // be released.
-  CR_DEFINE_STATIC_LOCAL(base::MemoryMappedFile, mapped_file, ());
+  CR_DEFINE_STATIC_LOCAL(MemoryMappedFile, mapped_file, ());
   if (!mapped_file.IsValid()) {
 #if !defined(OS_MACOSX)
     FilePath data_path;
 #if defined(OS_WIN)
     // The data file will be in the same directory as the current module.
-    bool path_ok = PathService::Get(base::DIR_MODULE, &data_path);
+    bool path_ok = PathService::Get(DIR_MODULE, &data_path);
     wchar_t tmp_buffer[_MAX_PATH] = {0};
     wcscpy_s(tmp_buffer, data_path.value().c_str());
-    base::debug::Alias(tmp_buffer);
+    debug::Alias(tmp_buffer);
     CHECK(path_ok);  // TODO(scottmg): http://crbug.com/445616
 #elif defined(OS_ANDROID)
-    bool path_ok = PathService::Get(base::DIR_ANDROID_APP_DATA, &data_path);
+    bool path_ok = PathService::Get(DIR_ANDROID_APP_DATA, &data_path);
 #else
     // For now, expect the data file to be alongside the executable.
     // This is sufficient while we work on unit tests, but will eventually
     // likely live in a data directory.
-    bool path_ok = PathService::Get(base::DIR_EXE, &data_path);
+    bool path_ok = PathService::Get(DIR_EXE, &data_path);
 #endif
     DCHECK(path_ok);
     data_path = data_path.AppendASCII(kIcuDataFileName);
@@ -154,15 +152,15 @@
     // TODO(scottmg): http://crbug.com/445616
     wchar_t tmp_buffer2[_MAX_PATH] = {0};
     wcscpy_s(tmp_buffer2, data_path.value().c_str());
-    base::debug::Alias(tmp_buffer2);
+    debug::Alias(tmp_buffer2);
 #endif
 
 #else
     // Assume it is in the framework bundle's Resources directory.
-    base::ScopedCFTypeRef<CFStringRef> data_file_name(
+    ScopedCFTypeRef<CFStringRef> data_file_name(
         SysUTF8ToCFStringRef(kIcuDataFileName));
     FilePath data_path =
-      base::mac::PathForFrameworkBundleResource(data_file_name);
+      mac::PathForFrameworkBundleResource(data_file_name);
     if (data_path.empty()) {
       LOG(ERROR) << kIcuDataFileName << " not found in bundle";
       return false;
diff --git a/base/i18n/icu_util.h b/base/i18n/icu_util.h
index e9f7c3d..65de0ad 100644
--- a/base/i18n/icu_util.h
+++ b/base/i18n/icu_util.h
@@ -18,14 +18,12 @@
 // Call this function to load ICU's data tables for the current process.  This
 // function should be called before ICU is used.
 BASE_I18N_EXPORT bool InitializeICU();
-#endif
 
-#if defined(OS_ANDROID)
-// Android uses a file descriptor passed by browser process to initialize ICU
-// in render processes.
+// Android and html_viewer use a file descriptor passed by browser process to
+// initialize ICU in render processes.
 BASE_I18N_EXPORT bool InitializeICUWithFileDescriptor(
-    int data_fd,
-    base::MemoryMappedFile::Region data_region);
+    PlatformFile data_fd,
+    MemoryMappedFile::Region data_region);
 #endif
 
 // In a test binary, the call above might occur twice.
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index e9a27bc..4d79be3 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -932,7 +932,7 @@
         return NULL;
       }
       NextNChars(kNullLen - 1);
-      return Value::CreateNullValue();
+      return Value::CreateNullValue().release();
     }
     default:
       ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index ae46800..5ac2590 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -12,75 +12,63 @@
   std::string output_js;
 
   // Test null.
-  Value* root = Value::CreateNullValue();
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  EXPECT_TRUE(JSONWriter::Write(Value::CreateNullValue().get(), &output_js));
   EXPECT_EQ("null", output_js);
-  delete root;
 
   // Test empty dict.
-  root = new DictionaryValue;
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  DictionaryValue dict;
+  EXPECT_TRUE(JSONWriter::Write(&dict, &output_js));
   EXPECT_EQ("{}", output_js);
-  delete root;
 
   // Test empty list.
-  root = new ListValue;
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  ListValue list;
+  EXPECT_TRUE(JSONWriter::Write(&list, &output_js));
   EXPECT_EQ("[]", output_js);
-  delete root;
 
   // Test integer values.
-  root = new FundamentalValue(42);
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  FundamentalValue int_value(42);
+  EXPECT_TRUE(JSONWriter::Write(&int_value, &output_js));
   EXPECT_EQ("42", output_js);
-  delete root;
 
   // Test boolean values.
-  root = new FundamentalValue(true);
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  FundamentalValue bool_value(true);
+  EXPECT_TRUE(JSONWriter::Write(&bool_value, &output_js));
   EXPECT_EQ("true", output_js);
-  delete root;
 
   // Test Real values should always have a decimal or an 'e'.
-  root = new FundamentalValue(1.0);
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  FundamentalValue double_value(1.0);
+  EXPECT_TRUE(JSONWriter::Write(&double_value, &output_js));
   EXPECT_EQ("1.0", output_js);
-  delete root;
 
   // Test Real values in the the range (-1, 1) must have leading zeros
-  root = new FundamentalValue(0.2);
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  FundamentalValue double_value2(0.2);
+  EXPECT_TRUE(JSONWriter::Write(&double_value2, &output_js));
   EXPECT_EQ("0.2", output_js);
-  delete root;
 
   // Test Real values in the the range (-1, 1) must have leading zeros
-  root = new FundamentalValue(-0.8);
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  FundamentalValue double_value3(-0.8);
+  EXPECT_TRUE(JSONWriter::Write(&double_value3, &output_js));
   EXPECT_EQ("-0.8", output_js);
-  delete root;
 
   // Test String values.
-  root = new StringValue("foo");
-  EXPECT_TRUE(JSONWriter::Write(root, &output_js));
+  StringValue string_value("foo");
+  EXPECT_TRUE(JSONWriter::Write(&string_value, &output_js));
   EXPECT_EQ("\"foo\"", output_js);
-  delete root;
 }
 
-
 TEST(JSONWriterTest, NestedTypes) {
   std::string output_js;
 
   // Writer unittests like empty list/dict nesting,
   // list list nesting, etc.
   DictionaryValue root_dict;
-  ListValue* list = new ListValue;
-  root_dict.Set("list", list);
-  DictionaryValue* inner_dict = new DictionaryValue;
-  list->Append(inner_dict);
+  scoped_ptr<ListValue> list(new ListValue());
+  scoped_ptr<DictionaryValue> inner_dict(new DictionaryValue());
   inner_dict->SetInteger("inner int", 10);
-  ListValue* inner_list = new ListValue;
-  list->Append(inner_list);
-  list->Append(new FundamentalValue(true));
+  list->Append(inner_dict.Pass());
+  list->Append(make_scoped_ptr(new ListValue()));
+  list->AppendBoolean(true);
+  root_dict.Set("list", list.Pass());
 
   // Test the pretty-printer.
   EXPECT_TRUE(JSONWriter::Write(&root_dict, &output_js));
@@ -109,17 +97,17 @@
   std::string output_js;
 
   DictionaryValue period_dict;
-  period_dict.SetWithoutPathExpansion("a.b", new FundamentalValue(3));
-  period_dict.SetWithoutPathExpansion("c", new FundamentalValue(2));
-  DictionaryValue* period_dict2 = new DictionaryValue;
-  period_dict2->SetWithoutPathExpansion("g.h.i.j", new FundamentalValue(1));
-  period_dict.SetWithoutPathExpansion("d.e.f", period_dict2);
+  period_dict.SetIntegerWithoutPathExpansion("a.b", 3);
+  period_dict.SetIntegerWithoutPathExpansion("c", 2);
+  scoped_ptr<DictionaryValue> period_dict2(new DictionaryValue());
+  period_dict2->SetIntegerWithoutPathExpansion("g.h.i.j", 1);
+  period_dict.SetWithoutPathExpansion("d.e.f", period_dict2.Pass());
   EXPECT_TRUE(JSONWriter::Write(&period_dict, &output_js));
   EXPECT_EQ("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}", output_js);
 
   DictionaryValue period_dict3;
-  period_dict3.Set("a.b", new FundamentalValue(2));
-  period_dict3.SetWithoutPathExpansion("a.b", new FundamentalValue(1));
+  period_dict3.SetInteger("a.b", 2);
+  period_dict3.SetIntegerWithoutPathExpansion("a.b", 1);
   EXPECT_TRUE(JSONWriter::Write(&period_dict3, &output_js));
   EXPECT_EQ("{\"a\":{\"b\":2},\"a.b\":1}", output_js);
 }
@@ -129,18 +117,17 @@
 
   // Binary values should return errors unless suppressed via the
   // OPTIONS_OMIT_BINARY_VALUES flag.
-  Value* root = BinaryValue::CreateWithCopiedBuffer("asdf", 4);
-  EXPECT_FALSE(JSONWriter::Write(root, &output_js));
+  scoped_ptr<Value> root(BinaryValue::CreateWithCopiedBuffer("asdf", 4));
+  EXPECT_FALSE(JSONWriter::Write(root.get(), &output_js));
   EXPECT_TRUE(JSONWriter::WriteWithOptions(
-      root, JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
+      root.get(), JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
   EXPECT_TRUE(output_js.empty());
-  delete root;
 
   ListValue binary_list;
   binary_list.Append(BinaryValue::CreateWithCopiedBuffer("asdf", 4));
-  binary_list.Append(new FundamentalValue(5));
+  binary_list.Append(make_scoped_ptr(new FundamentalValue(5)));
   binary_list.Append(BinaryValue::CreateWithCopiedBuffer("asdf", 4));
-  binary_list.Append(new FundamentalValue(2));
+  binary_list.Append(make_scoped_ptr(new FundamentalValue(2)));
   binary_list.Append(BinaryValue::CreateWithCopiedBuffer("asdf", 4));
   EXPECT_FALSE(JSONWriter::Write(&binary_list, &output_js));
   EXPECT_TRUE(JSONWriter::WriteWithOptions(
@@ -148,11 +135,14 @@
   EXPECT_EQ("[5,2]", output_js);
 
   DictionaryValue binary_dict;
-  binary_dict.Set("a", BinaryValue::CreateWithCopiedBuffer("asdf", 4));
-  binary_dict.Set("b", new FundamentalValue(5));
-  binary_dict.Set("c", BinaryValue::CreateWithCopiedBuffer("asdf", 4));
-  binary_dict.Set("d", new FundamentalValue(2));
-  binary_dict.Set("e", BinaryValue::CreateWithCopiedBuffer("asdf", 4));
+  binary_dict.Set(
+      "a", make_scoped_ptr(BinaryValue::CreateWithCopiedBuffer("asdf", 4)));
+  binary_dict.SetInteger("b", 5);
+  binary_dict.Set(
+      "c", make_scoped_ptr(BinaryValue::CreateWithCopiedBuffer("asdf", 4)));
+  binary_dict.SetInteger("d", 2);
+  binary_dict.Set(
+      "e", make_scoped_ptr(BinaryValue::CreateWithCopiedBuffer("asdf", 4)));
   EXPECT_FALSE(JSONWriter::Write(&binary_dict, &output_js));
   EXPECT_TRUE(JSONWriter::WriteWithOptions(
       &binary_dict, JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
diff --git a/base/json/string_escape_unittest.cc b/base/json/string_escape_unittest.cc
index 3eb4e8e..100373f 100644
--- a/base/json/string_escape_unittest.cc
+++ b/base/json/string_escape_unittest.cc
@@ -159,7 +159,7 @@
     const char* escaped;
   } cases[] = {
     {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"},
-    {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
+    {"\xe5\xc4\x4f\x05\xb6\xfd", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
   };
 
   for (size_t i = 0; i < arraysize(cases); ++i) {
diff --git a/base/mac/dispatch_source_mach.cc b/base/mac/dispatch_source_mach.cc
new file mode 100644
index 0000000..745c9de
--- /dev/null
+++ b/base/mac/dispatch_source_mach.cc
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/mac/dispatch_source_mach.h"
+
+namespace base {
+
+DispatchSourceMach::DispatchSourceMach(const char* name,
+                                       mach_port_t port,
+                                       void (^event_handler)())
+    // TODO(rsesek): Specify DISPATCH_QUEUE_SERIAL, in the 10.7 SDK. NULL
+    // means the same thing but is not symbolically clear.
+    : DispatchSourceMach(dispatch_queue_create(name, NULL),
+                         port,
+                         event_handler) {
+  // Since the queue was created above in the delegated constructor, and it was
+  // subsequently retained, release it here.
+  dispatch_release(queue_);
+}
+
+DispatchSourceMach::DispatchSourceMach(dispatch_queue_t queue,
+                                       mach_port_t port,
+                                       void (^event_handler)())
+    : queue_(queue),
+      source_(dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
+          port, 0, queue_)),
+      source_canceled_(dispatch_semaphore_create(0)) {
+  dispatch_retain(queue);
+
+  dispatch_source_set_event_handler(source_, event_handler);
+  dispatch_source_set_cancel_handler(source_, ^{
+      dispatch_semaphore_signal(source_canceled_);
+  });
+}
+
+DispatchSourceMach::~DispatchSourceMach() {
+  Cancel();
+}
+
+void DispatchSourceMach::Resume() {
+  dispatch_resume(source_);
+}
+
+void DispatchSourceMach::Cancel() {
+  if (source_) {
+    dispatch_source_cancel(source_);
+    dispatch_release(source_);
+    source_ = NULL;
+
+    dispatch_semaphore_wait(source_canceled_, DISPATCH_TIME_FOREVER);
+    dispatch_release(source_canceled_);
+    source_canceled_ = NULL;
+  }
+
+  if (queue_) {
+    dispatch_release(queue_);
+    queue_ = NULL;
+  }
+}
+
+}  // namespace base
diff --git a/base/mac/dispatch_source_mach.h b/base/mac/dispatch_source_mach.h
new file mode 100644
index 0000000..e7d5cb2
--- /dev/null
+++ b/base/mac/dispatch_source_mach.h
@@ -0,0 +1,61 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MAC_DISPATCH_SOURCE_MACH_H_
+#define BASE_MAC_DISPATCH_SOURCE_MACH_H_
+
+#include <dispatch/dispatch.h>
+
+#include "base/base_export.h"
+#include "base/macros.h"
+
+namespace base {
+
+// This class encapsulates a MACH_RECV dispatch source. When this object is
+// destroyed, the source will be cancelled and it will wait for the source
+// to stop executing work. The source can run on either a user-supplied queue,
+// or it can create its own for the source.
+class BASE_EXPORT DispatchSourceMach {
+ public:
+  // Creates a new dispatch source for the |port| and schedules it on a new
+  // queue that will be created with |name|. When a Mach message is received,
+  // the |event_handler| will be called.
+  DispatchSourceMach(const char* name,
+                     mach_port_t port,
+                     void (^event_handler)());
+
+  // Creates a new dispatch source with the same semantics as above, but rather
+  // than creating a new queue, it schedules the source on |queue|.
+  DispatchSourceMach(dispatch_queue_t queue,
+                     mach_port_t port,
+                     void (^event_handler)());
+
+  // Cancels the source and waits for it to become fully cancelled before
+  // releasing the source.
+  ~DispatchSourceMach();
+
+  // Resumes the source. This must be called before any Mach messages will
+  // be received.
+  void Resume();
+
+ private:
+  // Cancels the source, after which this class will no longer receive Mach
+  // messages. Calling this more than once is a no-op.
+  void Cancel();
+
+  // The dispatch queue used to service the source_.
+  dispatch_queue_t queue_;
+
+  // A MACH_RECV dispatch source.
+  dispatch_source_t source_;
+
+  // Semaphore used to wait on the |source_|'s cancellation in the destructor.
+  dispatch_semaphore_t source_canceled_;
+
+  DISALLOW_COPY_AND_ASSIGN(DispatchSourceMach);
+};
+
+}  // namespace base
+
+#endif  // BASE_MAC_DISPATCH_SOURCE_MACH_H_
diff --git a/base/mac/dispatch_source_mach_unittest.cc b/base/mac/dispatch_source_mach_unittest.cc
new file mode 100644
index 0000000..82dc136
--- /dev/null
+++ b/base/mac/dispatch_source_mach_unittest.cc
@@ -0,0 +1,125 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/mac/dispatch_source_mach.h"
+
+#include <mach/mach.h>
+
+#include "base/logging.h"
+#include "base/mac/scoped_mach_port.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/test/test_timeouts.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class DispatchSourceMachTest : public testing::Test {
+ public:
+  void SetUp() override {
+    mach_port_t port = MACH_PORT_NULL;
+    ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(mach_task_self(),
+        MACH_PORT_RIGHT_RECEIVE, &port));
+    receive_right_.reset(port);
+
+    ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(mach_task_self(), port,
+        port, MACH_MSG_TYPE_MAKE_SEND));
+    send_right_.reset(port);
+  }
+
+  mach_port_t GetPort() { return receive_right_.get(); }
+
+  void WaitForSemaphore(dispatch_semaphore_t semaphore) {
+    dispatch_semaphore_wait(semaphore, dispatch_time(
+        DISPATCH_TIME_NOW,
+        TestTimeouts::action_timeout().InSeconds() * NSEC_PER_SEC));
+  }
+
+ private:
+  base::mac::ScopedMachReceiveRight receive_right_;
+  base::mac::ScopedMachSendRight send_right_;
+};
+
+TEST_F(DispatchSourceMachTest, ReceiveAfterResume) {
+  dispatch_semaphore_t signal = dispatch_semaphore_create(0);
+  mach_port_t port = GetPort();
+
+  bool __block did_receive = false;
+  DispatchSourceMach source("org.chromium.base.test.ReceiveAfterResume",
+      port, ^{
+          mach_msg_empty_rcv_t msg = {{0}};
+          msg.header.msgh_size = sizeof(msg);
+          msg.header.msgh_local_port = port;
+          mach_msg_receive(&msg.header);
+          did_receive = true;
+
+          dispatch_semaphore_signal(signal);
+      });
+
+  mach_msg_empty_send_t msg = {{0}};
+  msg.header.msgh_size = sizeof(msg);
+  msg.header.msgh_remote_port = port;
+  msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
+  ASSERT_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));
+
+  EXPECT_FALSE(did_receive);
+
+  source.Resume();
+
+  WaitForSemaphore(signal);
+  dispatch_release(signal);
+
+  EXPECT_TRUE(did_receive);
+}
+
+TEST_F(DispatchSourceMachTest, NoMessagesAfterDestruction) {
+  mach_port_t port = GetPort();
+
+  scoped_ptr<int> count(new int(0));
+  int* __block count_ptr = count.get();
+
+  scoped_ptr<DispatchSourceMach> source(new DispatchSourceMach(
+      "org.chromium.base.test.NoMessagesAfterDestruction",
+      port, ^{
+          mach_msg_empty_rcv_t msg = {{0}};
+          msg.header.msgh_size = sizeof(msg);
+          msg.header.msgh_local_port = port;
+          mach_msg_receive(&msg.header);
+          LOG(INFO) << "Receieve " << *count_ptr;
+          ++(*count_ptr);
+      }));
+  source->Resume();
+
+  dispatch_queue_t queue =
+      dispatch_queue_create("org.chromium.base.test.MessageSend", NULL);
+  dispatch_semaphore_t signal = dispatch_semaphore_create(0);
+  for (int i = 0; i < 30; ++i) {
+    dispatch_async(queue, ^{
+        mach_msg_empty_send_t msg = {{0}};
+        msg.header.msgh_size = sizeof(msg);
+        msg.header.msgh_remote_port = port;
+        msg.header.msgh_bits =
+            MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
+        mach_msg_send(&msg.header);
+    });
+
+    // After sending five messages, shut down the source and taint the
+    // pointer the handler dereferences. The test will crash if |count_ptr|
+    // is being used after "free".
+    if (i == 5) {
+      scoped_ptr<DispatchSourceMach>* source_ptr = &source;
+      dispatch_async(queue, ^{
+          source_ptr->reset();
+          count_ptr = reinterpret_cast<int*>(0xdeaddead);
+          dispatch_semaphore_signal(signal);
+      });
+    }
+  }
+
+  WaitForSemaphore(signal);
+  dispatch_release(signal);
+
+  dispatch_release(queue);
+}
+
+}  // namespace base
diff --git a/base/mac/memory_pressure_monitor_mac.h b/base/mac/memory_pressure_monitor_mac.h
index aebdd65..8dc2622 100644
--- a/base/mac/memory_pressure_monitor_mac.h
+++ b/base/mac/memory_pressure_monitor_mac.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#ifndef BASE_MAC_MEMORY_PRESSURE_MONITOR_MAC_H_
+#define BASE_MAC_MEMORY_PRESSURE_MONITOR_MAC_H_
 
 #include <dispatch/dispatch.h>
 
@@ -59,4 +59,4 @@
 
 }  // namespace base
 
-#endif  // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#endif  // BASE_MAC_MEMORY_PRESSURE_MONITOR_MAC_H_
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index d7be320..d70a6aa 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -244,6 +244,8 @@
 BASE_EXPORT extern NSString* const
     NSWindowDidChangeBackingPropertiesNotification;
 BASE_EXPORT extern NSString* const CBAdvertisementDataServiceDataKey;
+BASE_EXPORT extern NSString* const
+    NSPreferredScrollerStyleDidChangeNotification;
 #endif  // MAC_OS_X_VERSION_10_7
 
 #if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/mac/sdk_forward_declarations.mm b/base/mac/sdk_forward_declarations.mm
index 347e87c..2e4b2d9 100644
--- a/base/mac/sdk_forward_declarations.mm
+++ b/base/mac/sdk_forward_declarations.mm
@@ -22,6 +22,9 @@
     @"NSWindowDidChangeBackingPropertiesNotification";
 
 NSString* const CBAdvertisementDataServiceDataKey = @"kCBAdvDataServiceData";
+
+NSString* const NSPreferredScrollerStyleDidChangeNotification =
+    @"NSPreferredScrollerStyleDidChangeNotification";
 #endif  // MAC_OS_X_VERSION_10_7
 
 #if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/macros.h b/base/macros.h
index 3ea576c..d904328 100644
--- a/base/macros.h
+++ b/base/macros.h
@@ -52,18 +52,8 @@
 // This template function declaration is used in defining arraysize.
 // Note that the function doesn't need an implementation, as we only
 // use its type.
-template <typename T, size_t N>
-char (&ArraySizeHelper(T (&array)[N]))[N];
-
-// That gcc wants both of these prototypes seems mysterious. VC, for
-// its part, can't decide which to use (another mystery). Matching of
-// template overloads: the final frontier.
-#ifndef _MSC_VER
-template <typename T, size_t N>
-char (&ArraySizeHelper(const T (&array)[N]))[N];
-#endif
-
-#define arraysize(array) (sizeof(::ArraySizeHelper(array)))
+template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
 
 
 // Use implicit_cast as a safe version of static_cast or const_cast
diff --git a/base/md5_unittest.cc b/base/md5_unittest.cc
index 8d817e9..08c99f1 100644
--- a/base/md5_unittest.cc
+++ b/base/md5_unittest.cc
@@ -246,7 +246,7 @@
   EXPECT_TRUE(!memcmp(&header_digest, &check_header_digest,
                       sizeof(header_digest)));
   EXPECT_TRUE(!memcmp(&digest, &check_full_digest, sizeof(digest)));
-  EXPECT_FALSE(!memcmp(&digest, &header_digest, sizeof(digest)));
+  EXPECT_TRUE(memcmp(&digest, &header_digest, sizeof(digest)));
 }
 
 }  // namespace base
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h
index 9aeeaca..50260c4 100644
--- a/base/memory/memory_pressure_monitor.h
+++ b/base/memory/memory_pressure_monitor.h
@@ -20,6 +20,8 @@
  public:
   using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
 
+  virtual ~MemoryPressureMonitor();
+
   // Return the singleton MemoryPressureMonitor.
   static MemoryPressureMonitor* Get();
 
@@ -28,7 +30,6 @@
 
  protected:
   MemoryPressureMonitor();
-  virtual ~MemoryPressureMonitor();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc
index 5e9a461..c1ce939 100644
--- a/base/message_loop/incoming_task_queue.cc
+++ b/base/message_loop/incoming_task_queue.cc
@@ -44,8 +44,7 @@
       message_loop_(message_loop),
       next_sequence_num_(0),
       message_loop_scheduled_(false),
-      always_schedule_work_(AlwaysNotifyPump(message_loop_->type())),
-      is_ready_for_scheduling_(false) {
+      always_schedule_work_(AlwaysNotifyPump(message_loop_->type())) {
 }
 
 bool IncomingTaskQueue::AddToIncomingQueue(
@@ -110,15 +109,6 @@
   message_loop_ = NULL;
 }
 
-void IncomingTaskQueue::StartScheduling() {
-  AutoLock lock(incoming_queue_lock_);
-  DCHECK(!is_ready_for_scheduling_);
-  DCHECK(!message_loop_scheduled_);
-  is_ready_for_scheduling_ = true;
-  if (!incoming_queue_.empty())
-    ScheduleWork();
-}
-
 IncomingTaskQueue::~IncomingTaskQueue() {
   // Verify that WillDestroyCurrentMessageLoop() has been called.
   DCHECK(!message_loop_);
@@ -158,25 +148,19 @@
   incoming_queue_.push(*pending_task);
   pending_task->task.Reset();
 
-  if (is_ready_for_scheduling_ &&
-      (always_schedule_work_ || (!message_loop_scheduled_ && was_empty))) {
-    ScheduleWork();
+  if (always_schedule_work_ || (!message_loop_scheduled_ && was_empty)) {
+    // Wake up the message loop.
+    message_loop_->ScheduleWork();
+    // After we've scheduled the message loop, we do not need to do so again
+    // until we know it has processed all of the work in our queue and is
+    // waiting for more work again. The message loop will always attempt to
+    // reload from the incoming queue before waiting again so we clear this flag
+    // in ReloadWorkQueue().
+    message_loop_scheduled_ = true;
   }
 
   return true;
 }
 
-void IncomingTaskQueue::ScheduleWork() {
-  DCHECK(is_ready_for_scheduling_);
-  // Wake up the message loop.
-  message_loop_->ScheduleWork();
-  // After we've scheduled the message loop, we do not need to do so again
-  // until we know it has processed all of the work in our queue and is
-  // waiting for more work again. The message loop will always attempt to
-  // reload from the incoming queue before waiting again so we clear this flag
-  // in ReloadWorkQueue().
-  message_loop_scheduled_ = true;
-}
-
 }  // namespace internal
 }  // namespace base
diff --git a/base/message_loop/incoming_task_queue.h b/base/message_loop/incoming_task_queue.h
index 7dd1e82..72e1f30 100644
--- a/base/message_loop/incoming_task_queue.h
+++ b/base/message_loop/incoming_task_queue.h
@@ -53,10 +53,6 @@
   // Disconnects |this| from the parent message loop.
   void WillDestroyCurrentMessageLoop();
 
-  // This should be called when the message loop becomes ready for
-  // scheduling work.
-  void StartScheduling();
-
  private:
   friend class RefCountedThreadSafe<IncomingTaskQueue>;
   virtual ~IncomingTaskQueue();
@@ -70,9 +66,6 @@
   // does not retain |pending_task->task| beyond this function call.
   bool PostPendingTask(PendingTask* pending_task);
 
-  // Wakes up the message loop and schedules work.
-  void ScheduleWork();
-
   // Number of tasks that require high resolution timing. This value is kept
   // so that ReloadWorkQueue() completes in constant time.
   int high_res_task_count_;
@@ -99,9 +92,6 @@
   // if the incoming queue was not empty.
   const bool always_schedule_work_;
 
-  // False until StartScheduling() is called.
-  bool is_ready_for_scheduling_;
-
   DISALLOW_COPY_AND_ASSIGN(IncomingTaskQueue);
 };
 
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 4222c77..eb0f968 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -100,10 +100,6 @@
 }
 #endif  // !defined(OS_NACL_SFI)
 
-scoped_ptr<MessagePump> ReturnPump(scoped_ptr<MessagePump> pump) {
-  return pump;
-}
-
 }  // namespace
 
 //------------------------------------------------------------------------------
@@ -120,19 +116,41 @@
 //------------------------------------------------------------------------------
 
 MessageLoop::MessageLoop(Type type)
-    : MessageLoop(type, MessagePumpFactoryCallback()) {
-  BindToCurrentThread();
+    : type_(type),
+#if defined(OS_WIN)
+      pending_high_res_tasks_(0),
+      in_high_res_mode_(false),
+#endif
+      nestable_tasks_allowed_(true),
+#if defined(OS_WIN)
+      os_modal_loop_(false),
+#endif  // OS_WIN
+      message_histogram_(NULL),
+      run_loop_(NULL) {
+  Init();
+
+  pump_ = CreateMessagePumpForType(type).Pass();
 }
 
 MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump)
-    : MessageLoop(TYPE_CUSTOM, Bind(&ReturnPump, Passed(&pump))) {
-  BindToCurrentThread();
+    : pump_(pump.Pass()),
+      type_(TYPE_CUSTOM),
+#if defined(OS_WIN)
+      pending_high_res_tasks_(0),
+      in_high_res_mode_(false),
+#endif
+      nestable_tasks_allowed_(true),
+#if defined(OS_WIN)
+      os_modal_loop_(false),
+#endif  // OS_WIN
+      message_histogram_(NULL),
+      run_loop_(NULL) {
+  DCHECK(pump_.get());
+  Init();
 }
 
 MessageLoop::~MessageLoop() {
-  // current() could be NULL if this message loop is destructed before it is
-  // bound to a thread.
-  DCHECK(current() == this || !current());
+  DCHECK_EQ(this, current());
 
   // iOS just attaches to the loop, it doesn't Run it.
   // TODO(stuartmorgan): Consider wiring up a Detach().
@@ -281,13 +299,11 @@
 }
 
 void MessageLoop::Run() {
-  DCHECK(pump_);
   RunLoop run_loop;
   run_loop.Run();
 }
 
 void MessageLoop::RunUntilIdle() {
-  DCHECK(pump_);
   RunLoop run_loop;
   run_loop.RunUntilIdle();
 }
@@ -367,43 +383,13 @@
 
 //------------------------------------------------------------------------------
 
-scoped_ptr<MessageLoop> MessageLoop::CreateUnbound(
-    Type type, MessagePumpFactoryCallback pump_factory) {
-  return make_scoped_ptr(new MessageLoop(type, pump_factory));
-}
-
-MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
-    : type_(type),
-#if defined(OS_WIN)
-      pending_high_res_tasks_(0),
-      in_high_res_mode_(false),
-#endif
-      nestable_tasks_allowed_(true),
-#if defined(OS_WIN)
-      os_modal_loop_(false),
-#endif  // OS_WIN
-      pump_factory_(pump_factory),
-      message_histogram_(NULL),
-      run_loop_(NULL),
-      incoming_task_queue_(new internal::IncomingTaskQueue(this)),
-      message_loop_proxy_(
-          new internal::MessageLoopProxyImpl(incoming_task_queue_)) {
-  // If type is TYPE_CUSTOM non-null pump_factory must be given.
-  DCHECK_EQ(type_ == TYPE_CUSTOM, !pump_factory_.is_null());
-}
-
-void MessageLoop::BindToCurrentThread() {
-  DCHECK(!pump_);
-  if (!pump_factory_.is_null())
-    pump_ = pump_factory_.Run();
-  else
-    pump_ = CreateMessagePumpForType(type_);
-
+void MessageLoop::Init() {
   DCHECK(!current()) << "should only have one message loop per thread";
   lazy_tls_ptr.Pointer()->Set(this);
 
-  incoming_task_queue_->StartScheduling();
-  message_loop_proxy_->BindToCurrentThread();
+  incoming_task_queue_ = new internal::IncomingTaskQueue(this);
+  message_loop_proxy_ =
+      new internal::MessageLoopProxyImpl(incoming_task_queue_);
   thread_task_runner_handle_.reset(
       new ThreadTaskRunnerHandle(message_loop_proxy_));
 }
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index f2f89d0..fd7596a 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -114,8 +114,7 @@
   explicit MessageLoop(Type type = TYPE_DEFAULT);
   // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
   // be non-NULL.
-  explicit MessageLoop(scoped_ptr<MessagePump> pump);
-
+  explicit MessageLoop(scoped_ptr<base::MessagePump> pump);
   ~MessageLoop() override;
 
   // Returns the MessageLoop object for the current thread, or null if none.
@@ -395,6 +394,10 @@
   // Returns true if the message loop is "idle". Provided for testing.
   bool IsIdleForTesting();
 
+  // Wakes up the message pump. Can be called on any thread. The caller is
+  // responsible for synchronizing ScheduleWork() calls.
+  void ScheduleWork();
+
   // Returns the TaskAnnotator which is used to add debug information to posted
   // tasks.
   debug::TaskAnnotator* task_annotator() { return &task_annotator_; }
@@ -408,33 +411,9 @@
 
  private:
   friend class RunLoop;
-  friend class internal::IncomingTaskQueue;
-  friend class ScheduleWorkTest;
-  friend class Thread;
 
-  using MessagePumpFactoryCallback = Callback<scoped_ptr<MessagePump>()>;
-
-  // Creates a MessageLoop without binding to a thread.
-  // If |type| is TYPE_CUSTOM non-null |pump_factory| must be also given
-  // to create a message pump for this message loop.  Otherwise a default
-  // message pump for the |type| is created.
-  //
-  // It is valid to call this to create a new message loop on one thread,
-  // and then pass it to the thread where the message loop actually runs.
-  // The message loop's BindToCurrentThread() method must be called on the
-  // thread the message loop runs on, before calling Run().
-  // Before BindToCurrentThread() is called only Post*Task() functions can
-  // be called on the message loop.
-  scoped_ptr<MessageLoop> CreateUnbound(
-      Type type,
-      MessagePumpFactoryCallback pump_factory);
-
-  // Common private constructor. Other constructors delegate the initialization
-  // to this constructor.
-  MessageLoop(Type type, MessagePumpFactoryCallback pump_factory);
-
-  // Configure various members and bind this message loop to the current thread.
-  void BindToCurrentThread();
+  // Configures various members for the two constructors.
+  void Init();
 
   // Invokes the actual run loop using the message pump.
   void RunHandler();
@@ -458,10 +437,6 @@
   // empty.
   void ReloadWorkQueue();
 
-  // Wakes up the message pump. Can be called on any thread. The caller is
-  // responsible for synchronizing ScheduleWork() calls.
-  void ScheduleWork();
-
   // Start recording histogram info about events and action IF it was enabled
   // and IF the statistics recorder can accept a registration of our histogram.
   void StartHistogrammer();
@@ -515,10 +490,6 @@
   bool os_modal_loop_;
 #endif
 
-  // pump_factory_.Run() is called to create a message pump for this loop
-  // if type_ is TYPE_CUSTOM and pump_ is null.
-  MessagePumpFactoryCallback pump_factory_;
-
   std::string thread_name_;
   // A profiling histogram showing the counts of various messages and events.
   HistogramBase* message_histogram_;
diff --git a/base/message_loop/message_loop_proxy_impl.cc b/base/message_loop/message_loop_proxy_impl.cc
index 0da21a0..b7abca3 100644
--- a/base/message_loop/message_loop_proxy_impl.cc
+++ b/base/message_loop/message_loop_proxy_impl.cc
@@ -15,12 +15,7 @@
 MessageLoopProxyImpl::MessageLoopProxyImpl(
     scoped_refptr<IncomingTaskQueue> incoming_queue)
     : incoming_queue_(incoming_queue),
-      valid_thread_id_(kInvalidThreadId) {
-}
-
-void MessageLoopProxyImpl::BindToCurrentThread() {
-  DCHECK_EQ(kInvalidThreadId, valid_thread_id_);
-  valid_thread_id_ = PlatformThread::CurrentId();
+      valid_thread_id_(PlatformThread::CurrentId()) {
 }
 
 bool MessageLoopProxyImpl::PostDelayedTask(
diff --git a/base/message_loop/message_loop_proxy_impl.h b/base/message_loop/message_loop_proxy_impl.h
index c477320..0fe629f 100644
--- a/base/message_loop/message_loop_proxy_impl.h
+++ b/base/message_loop/message_loop_proxy_impl.h
@@ -24,9 +24,6 @@
   explicit MessageLoopProxyImpl(
       scoped_refptr<IncomingTaskQueue> incoming_queue);
 
-  // Initialize this message loop proxy on the current thread.
-  void BindToCurrentThread();
-
   // MessageLoopProxy implementation
   bool PostDelayedTask(const tracked_objects::Location& from_here,
                        const base::Closure& task,
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc
index 0bf3d0c..b3e5604 100644
--- a/base/message_loop/message_pump_perftest.cc
+++ b/base/message_loop/message_pump_perftest.cc
@@ -20,6 +20,7 @@
 #endif
 
 namespace base {
+namespace {
 
 class ScheduleWorkTest : public testing::Test {
  public:
@@ -223,6 +224,9 @@
 }
 #endif
 
+static void DoNothing() {
+}
+
 class FakeMessagePump : public MessagePump {
  public:
   FakeMessagePump() {}
@@ -285,4 +289,5 @@
   Run(1000, 100);
 }
 
+}  // namespace
 }  // namespace base
diff --git a/base/metrics/histogram_base.cc b/base/metrics/histogram_base.cc
index f09c84e..de34c79 100644
--- a/base/metrics/histogram_base.cc
+++ b/base/metrics/histogram_base.cc
@@ -111,8 +111,8 @@
   root.SetInteger("count", count);
   root.SetDouble("sum", static_cast<double>(sum));
   root.SetInteger("flags", flags());
-  root.Set("params", parameters.release());
-  root.Set("buckets", buckets.release());
+  root.Set("params", parameters.Pass());
+  root.Set("buckets", buckets.Pass());
   root.SetInteger("pid", GetCurrentProcId());
   serializer.Serialize(root);
 }
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index 39ecc30..fb069a5 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -286,8 +286,6 @@
 
 // static
 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
-  DCHECK(VLOG_IS_ON(1));
-
   string output;
   StatisticsRecorder::WriteGraph(std::string(), &output);
   VLOG(1) << output;
diff --git a/base/observer_list.h b/base/observer_list.h
index 9ea344d..fb6f026 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_OBSERVER_LIST_H__
-#define BASE_OBSERVER_LIST_H__
+#ifndef BASE_OBSERVER_LIST_H_
+#define BASE_OBSERVER_LIST_H_
 
 #include <algorithm>
 #include <limits>
@@ -240,4 +240,4 @@
     }                                                                    \
   } while (0)
 
-#endif  // BASE_OBSERVER_LIST_H__
+#endif  // BASE_OBSERVER_LIST_H_
diff --git a/base/pickle.h b/base/pickle.h
index e6b9d81..9589e2a 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_PICKLE_H__
-#define BASE_PICKLE_H__
+#ifndef BASE_PICKLE_H_
+#define BASE_PICKLE_H_
 
 #include <string>
 
@@ -304,4 +304,4 @@
   FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow);
 };
 
-#endif  // BASE_PICKLE_H__
+#endif  // BASE_PICKLE_H_
diff --git a/base/prefs/json_pref_store.cc b/base/prefs/json_pref_store.cc
index 416e43f..da545b8 100644
--- a/base/prefs/json_pref_store.cc
+++ b/base/prefs/json_pref_store.cc
@@ -150,17 +150,10 @@
     const base::FilePath& filename,
     const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
     scoped_ptr<PrefFilter> pref_filter)
-    : path_(filename),
-      sequenced_task_runner_(sequenced_task_runner),
-      prefs_(new base::DictionaryValue()),
-      read_only_(false),
-      writer_(filename, sequenced_task_runner),
-      pref_filter_(pref_filter.Pass()),
-      initialized_(false),
-      filtering_in_progress_(false),
-      read_error_(PREF_READ_ERROR_NONE),
-      write_count_histogram_(writer_.commit_interval(), path_) {
-  DCHECK(!path_.empty());
+    : JsonPrefStore(filename,
+                    base::FilePath(),
+                    sequenced_task_runner,
+                    pref_filter.Pass()) {
 }
 
 JsonPrefStore::JsonPrefStore(
@@ -177,6 +170,7 @@
       pref_filter_(pref_filter.Pass()),
       initialized_(false),
       filtering_in_progress_(false),
+      pending_lossy_write_(false),
       read_error_(PREF_READ_ERROR_NONE),
       write_count_histogram_(writer_.commit_interval(), path_) {
   DCHECK(!path_.empty());
@@ -226,7 +220,9 @@
   return prefs_->Get(key, result);
 }
 
-void JsonPrefStore::SetValue(const std::string& key, base::Value* value) {
+void JsonPrefStore::SetValue(const std::string& key,
+                             base::Value* value,
+                             uint32 flags) {
   DCHECK(CalledOnValidThread());
 
   DCHECK(value);
@@ -234,13 +230,14 @@
   base::Value* old_value = NULL;
   prefs_->Get(key, &old_value);
   if (!old_value || !value->Equals(old_value)) {
-    prefs_->Set(key, new_value.release());
-    ReportValueChanged(key);
+    prefs_->Set(key, new_value.Pass());
+    ReportValueChanged(key, flags);
   }
 }
 
 void JsonPrefStore::SetValueSilently(const std::string& key,
-                                     base::Value* value) {
+                                     base::Value* value,
+                                     uint32 flags) {
   DCHECK(CalledOnValidThread());
 
   DCHECK(value);
@@ -248,25 +245,23 @@
   base::Value* old_value = NULL;
   prefs_->Get(key, &old_value);
   if (!old_value || !value->Equals(old_value)) {
-    prefs_->Set(key, new_value.release());
-    if (!read_only_)
-      writer_.ScheduleWrite(this);
+    prefs_->Set(key, new_value.Pass());
+    ScheduleWrite(flags);
   }
 }
 
-void JsonPrefStore::RemoveValue(const std::string& key) {
+void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) {
   DCHECK(CalledOnValidThread());
 
   if (prefs_->RemovePath(key, NULL))
-    ReportValueChanged(key);
+    ReportValueChanged(key, flags);
 }
 
-void JsonPrefStore::RemoveValueSilently(const std::string& key) {
+void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) {
   DCHECK(CalledOnValidThread());
 
   prefs_->RemovePath(key, NULL);
-  if (!read_only_)
-    writer_.ScheduleWrite(this);
+  ScheduleWrite(flags);
 }
 
 bool JsonPrefStore::ReadOnly() const {
@@ -306,11 +301,16 @@
 void JsonPrefStore::CommitPendingWrite() {
   DCHECK(CalledOnValidThread());
 
+  // Schedule a write for any lossy writes that are outstanding to ensure that
+  // they get flushed when this function is called.
+  if (pending_lossy_write_)
+    writer_.ScheduleWrite(this);
+
   if (writer_.HasPendingWrite() && !read_only_)
     writer_.DoScheduledWrite();
 }
 
-void JsonPrefStore::ReportValueChanged(const std::string& key) {
+void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) {
   DCHECK(CalledOnValidThread());
 
   if (pref_filter_)
@@ -318,8 +318,7 @@
 
   FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
 
-  if (!read_only_)
-    writer_.ScheduleWrite(this);
+  ScheduleWrite(flags);
 }
 
 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
@@ -398,6 +397,8 @@
 bool JsonPrefStore::SerializeData(std::string* output) {
   DCHECK(CalledOnValidThread());
 
+  pending_lossy_write_ = false;
+
   write_count_histogram_.RecordWriteOccured();
 
   if (pref_filter_)
@@ -429,8 +430,8 @@
 
   initialized_ = true;
 
-  if (schedule_write && !read_only_)
-    writer_.ScheduleWrite(this);
+  if (schedule_write)
+    ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
 
   if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
     error_delegate_->OnError(read_error_);
@@ -442,6 +443,16 @@
   return;
 }
 
+void JsonPrefStore::ScheduleWrite(uint32 flags) {
+  if (read_only_)
+    return;
+
+  if (flags & LOSSY_PREF_WRITE_FLAG)
+    pending_lossy_write_ = true;
+  else
+    writer_.ScheduleWrite(this);
+}
+
 // NOTE: This value should NOT be changed without renaming the histogram
 // otherwise it will create incompatible buckets.
 const int32_t
diff --git a/base/prefs/json_pref_store.h b/base/prefs/json_pref_store.h
index 1badcf2..ef260eb 100644
--- a/base/prefs/json_pref_store.h
+++ b/base/prefs/json_pref_store.h
@@ -29,6 +29,7 @@
 class DictionaryValue;
 class FilePath;
 class HistogramBase;
+class JsonPrefStoreLossyWriteTest;
 class SequencedTaskRunner;
 class SequencedWorkerPool;
 class Value;
@@ -82,9 +83,13 @@
 
   // PersistentPrefStore overrides:
   bool GetMutableValue(const std::string& key, base::Value** result) override;
-  void SetValue(const std::string& key, base::Value* value) override;
-  void SetValueSilently(const std::string& key, base::Value* value) override;
-  void RemoveValue(const std::string& key) override;
+  void SetValue(const std::string& key,
+                base::Value* value,
+                uint32 flags) override;
+  void SetValueSilently(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) override;
+  void RemoveValue(const std::string& key, uint32 flags) override;
   bool ReadOnly() const override;
   PrefReadError GetReadError() const override;
   // Note this method may be asynchronous if this instance has a |pref_filter_|
@@ -93,11 +98,11 @@
   PrefReadError ReadPrefs() override;
   void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
   void CommitPendingWrite() override;
-  void ReportValueChanged(const std::string& key) override;
+  void ReportValueChanged(const std::string& key, uint32 flags) override;
 
   // Just like RemoveValue(), but doesn't notify observers. Used when doing some
   // cleanup that shouldn't otherwise alert observers.
-  void RemoveValueSilently(const std::string& key);
+  void RemoveValueSilently(const std::string& key, uint32 flags);
 
   // Registers |on_next_successful_write| to be called once, on the next
   // successful write event of |writer_|.
@@ -161,6 +166,7 @@
                            WriteCountHistogramTestMultiplePeriods);
   FRIEND_TEST_ALL_PREFIXES(base::JsonPrefStoreTest,
                            WriteCountHistogramTestPeriodWithGaps);
+  friend class base::JsonPrefStoreLossyWriteTest;
 
   ~JsonPrefStore() override;
 
@@ -186,6 +192,10 @@
                         scoped_ptr<base::DictionaryValue> prefs,
                         bool schedule_write);
 
+  // Schedule a write with the file writer as long as |flags| doesn't contain
+  // WriteablePrefStore::LOSSY_PREF_WRITE_FLAG.
+  void ScheduleWrite(uint32 flags);
+
   const base::FilePath path_;
   const base::FilePath alternate_path_;
   const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
@@ -204,6 +214,7 @@
 
   bool initialized_;
   bool filtering_in_progress_;
+  bool pending_lossy_write_;
   PrefReadError read_error_;
 
   std::set<std::string> keys_need_empty_value_;
diff --git a/base/prefs/json_pref_store_unittest.cc b/base/prefs/json_pref_store_unittest.cc
index 728a57d..67a8adb 100644
--- a/base/prefs/json_pref_store_unittest.cc
+++ b/base/prefs/json_pref_store_unittest.cc
@@ -108,9 +108,7 @@
   void TearDown() override {
     // Make sure all pending tasks have been processed (e.g., deleting the
     // JsonPrefStore may post write tasks).
-    message_loop_.task_runner()->PostTask(FROM_HERE,
-                                          MessageLoop::QuitWhenIdleClosure());
-    message_loop_.Run();
+    RunLoop().RunUntilIdle();
   }
 
   // The path to temporary directory used to contain the test operations.
@@ -127,7 +125,7 @@
 
 // Test fallback behavior for a nonexistent file.
 TEST_F(JsonPrefStoreTest, NonExistentFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
       bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -138,9 +136,9 @@
 
 // Test fallback behavior for a nonexistent file and alternate file.
 TEST_F(JsonPrefStoreTest, NonExistentFileAndAlternateFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   base::FilePath bogus_alternate_input_file =
-      data_dir_.AppendASCII("read_alternate.txt");
+      temp_dir_.path().AppendASCII("read_alternate.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   ASSERT_FALSE(PathExists(bogus_alternate_input_file));
   scoped_refptr<JsonPrefStore> pref_store =
@@ -194,7 +192,8 @@
   EXPECT_EQ(base::FilePath::StringType(FILE_PATH_LITERAL("/usr/local/")), path);
   base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));
 
-  pref_store->SetValue(kSomeDirectory, new StringValue(some_path.value()));
+  pref_store->SetValue(kSomeDirectory, new StringValue(some_path.value()),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
   EXPECT_TRUE(actual->GetAsString(&path));
   EXPECT_EQ(some_path.value(), path);
@@ -205,7 +204,8 @@
   EXPECT_TRUE(actual->GetAsBoolean(&boolean));
   EXPECT_TRUE(boolean);
 
-  pref_store->SetValue(kNewWindowsInTabs, new FundamentalValue(false));
+  pref_store->SetValue(kNewWindowsInTabs, new FundamentalValue(false),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
   EXPECT_TRUE(actual->GetAsBoolean(&boolean));
   EXPECT_FALSE(boolean);
@@ -214,13 +214,15 @@
   int integer = 0;
   EXPECT_TRUE(actual->GetAsInteger(&integer));
   EXPECT_EQ(20, integer);
-  pref_store->SetValue(kMaxTabs, new FundamentalValue(10));
+  pref_store->SetValue(kMaxTabs, new FundamentalValue(10),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
   EXPECT_TRUE(actual->GetAsInteger(&integer));
   EXPECT_EQ(10, integer);
 
   pref_store->SetValue(kLongIntPref,
-                       new StringValue(base::Int64ToString(214748364842LL)));
+                       new StringValue(base::Int64ToString(214748364842LL)),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
   EXPECT_TRUE(actual->GetAsString(&string_value));
   int64 value;
@@ -310,12 +312,14 @@
       pref_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
 
   // Set some keys with empty values.
-  pref_store->SetValue("list", new base::ListValue);
-  pref_store->SetValue("dict", new base::DictionaryValue);
+  pref_store->SetValue("list", new base::ListValue,
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  pref_store->SetValue("dict", new base::DictionaryValue,
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   // Write to file.
   pref_store->CommitPendingWrite();
-  MessageLoop::current()->RunUntilIdle();
+  RunLoop().RunUntilIdle();
 
   // Reload.
   pref_store = new JsonPrefStore(pref_file, message_loop_.task_runner(),
@@ -341,9 +345,11 @@
 
   base::DictionaryValue* dict = new base::DictionaryValue;
   dict->SetString("key", "value");
-  pref_store->SetValue("dict", dict);
+  pref_store->SetValue("dict", dict,
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
-  pref_store->RemoveValue("dict.key");
+  pref_store->RemoveValue("dict.key",
+                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   const base::Value* retrieved_dict = NULL;
   bool has_dict = pref_store->GetValue("dict", &retrieved_dict);
@@ -352,7 +358,7 @@
 
 // Tests asynchronous reading of the file when there is no file.
 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
-  base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+  base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
   ASSERT_FALSE(PathExists(bogus_input_file));
   scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
       bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -801,4 +807,125 @@
   ASSERT_EQ(6, samples->TotalCount());
 }
 
+class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
+ protected:
+  void SetUp() override {
+    JsonPrefStoreTest::SetUp();
+    test_file_ = temp_dir_.path().AppendASCII("test.json");
+  }
+
+  // Creates a JsonPrefStore with the given |file_writer|.
+  scoped_refptr<JsonPrefStore> CreatePrefStore() {
+    return new JsonPrefStore(test_file_, message_loop_.task_runner(),
+                             scoped_ptr<PrefFilter>());
+  }
+
+  // Return the ImportantFileWriter for a given JsonPrefStore.
+  ImportantFileWriter* GetImportantFileWriter(
+      scoped_refptr<JsonPrefStore> pref_store) {
+    return &(pref_store->writer_);
+  }
+
+  // Get the contents of kTestFile. Pumps the message loop before returning the
+  // result.
+  std::string GetTestFileContents() {
+    RunLoop().RunUntilIdle();
+    std::string file_contents;
+    ReadFileToString(test_file_, &file_contents);
+    return file_contents;
+  }
+
+ private:
+  base::FilePath test_file_;
+};
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a normal pref and check that it gets scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Set a lossy pref and check that it is not scheduled to be written.
+  // SetValue/RemoveValue.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // SetValueSilently/RemoveValueSilently.
+  pref_store->SetValueSilently("lossy", new base::StringValue("lossy"),
+                               WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->RemoveValueSilently("lossy",
+                                  WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // ReportValueChanged.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->ReportValueChanged("lossy",
+                                 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Call CommitPendingWrite and check that the lossy pref and the normal pref
+  // are there with the last values set above.
+  pref_store->CommitPendingWrite();
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a lossy pref and check that it is not scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+
+  // Set a normal pref and check that it is scheduled to be written.
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Call DoScheduledWrite and check both prefs get written.
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
+  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+  // Set a normal pref and check that it is scheduled to be written.
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+  pref_store->SetValue("normal", new base::StringValue("normal"),
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Set a lossy pref and check that the write is still scheduled.
+  pref_store->SetValue("lossy", new base::StringValue("lossy"),
+                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+  ASSERT_TRUE(file_writer->HasPendingWrite());
+
+  // Call DoScheduledWrite and check both prefs get written.
+  file_writer->DoScheduledWrite();
+  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+            GetTestFileContents());
+  ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
 }  // namespace base
diff --git a/base/prefs/overlay_user_pref_store.cc b/base/prefs/overlay_user_pref_store.cc
index a708bb6..e93dffd 100644
--- a/base/prefs/overlay_user_pref_store.cc
+++ b/base/prefs/overlay_user_pref_store.cc
@@ -63,34 +63,36 @@
 }
 
 void OverlayUserPrefStore::SetValue(const std::string& key,
-                                    base::Value* value) {
+                                    base::Value* value,
+                                    uint32 flags) {
   if (!ShallBeStoredInOverlay(key)) {
-    underlay_->SetValue(GetUnderlayKey(key), value);
+    underlay_->SetValue(GetUnderlayKey(key), value, flags);
     return;
   }
 
   if (overlay_.SetValue(key, value))
-    ReportValueChanged(key);
+    ReportValueChanged(key, flags);
 }
 
 void OverlayUserPrefStore::SetValueSilently(const std::string& key,
-                                            base::Value* value) {
+                                            base::Value* value,
+                                            uint32 flags) {
   if (!ShallBeStoredInOverlay(key)) {
-    underlay_->SetValueSilently(GetUnderlayKey(key), value);
+    underlay_->SetValueSilently(GetUnderlayKey(key), value, flags);
     return;
   }
 
   overlay_.SetValue(key, value);
 }
 
-void OverlayUserPrefStore::RemoveValue(const std::string& key) {
+void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32 flags) {
   if (!ShallBeStoredInOverlay(key)) {
-    underlay_->RemoveValue(GetUnderlayKey(key));
+    underlay_->RemoveValue(GetUnderlayKey(key), flags);
     return;
   }
 
   if (overlay_.RemoveValue(key))
-    ReportValueChanged(key);
+    ReportValueChanged(key, flags);
 }
 
 bool OverlayUserPrefStore::ReadOnly() const {
@@ -119,13 +121,14 @@
   // We do not write our content intentionally.
 }
 
-void OverlayUserPrefStore::ReportValueChanged(const std::string& key) {
+void OverlayUserPrefStore::ReportValueChanged(const std::string& key,
+                                              uint32 flags) {
   FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
 }
 
 void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) {
   if (!overlay_.GetValue(GetOverlayKey(key), NULL))
-    ReportValueChanged(GetOverlayKey(key));
+    ReportValueChanged(GetOverlayKey(key), DEFAULT_PREF_WRITE_FLAGS);
 }
 
 void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) {
diff --git a/base/prefs/overlay_user_pref_store.h b/base/prefs/overlay_user_pref_store.h
index 5194a7b..04c309d 100644
--- a/base/prefs/overlay_user_pref_store.h
+++ b/base/prefs/overlay_user_pref_store.h
@@ -39,15 +39,19 @@
 
   // Methods of PersistentPrefStore.
   bool GetMutableValue(const std::string& key, base::Value** result) override;
-  void SetValue(const std::string& key, base::Value* value) override;
-  void SetValueSilently(const std::string& key, base::Value* value) override;
-  void RemoveValue(const std::string& key) override;
+  void SetValue(const std::string& key,
+                base::Value* value,
+                uint32 flags) override;
+  void SetValueSilently(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) override;
+  void RemoveValue(const std::string& key, uint32 flags) override;
   bool ReadOnly() const override;
   PrefReadError GetReadError() const override;
   PrefReadError ReadPrefs() override;
   void ReadPrefsAsync(ReadErrorDelegate* delegate) override;
   void CommitPendingWrite() override;
-  void ReportValueChanged(const std::string& key) override;
+  void ReportValueChanged(const std::string& key, uint32 flags) override;
 
   // Methods of PrefStore::Observer.
   void OnPrefValueChanged(const std::string& key) override;
diff --git a/base/prefs/overlay_user_pref_store_unittest.cc b/base/prefs/overlay_user_pref_store_unittest.cc
index 9836fbf..06b4ec9 100644
--- a/base/prefs/overlay_user_pref_store_unittest.cc
+++ b/base/prefs/overlay_user_pref_store_unittest.cc
@@ -48,38 +48,47 @@
   overlay_->AddObserver(&obs);
 
   // Check that underlay first value is reported.
-  underlay_->SetValue(overlay_key, new FundamentalValue(42));
+  underlay_->SetValue(overlay_key, new FundamentalValue(42),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(overlay_key);
 
   // Check that underlay overwriting is reported.
-  underlay_->SetValue(overlay_key, new FundamentalValue(43));
+  underlay_->SetValue(overlay_key, new FundamentalValue(43),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(overlay_key);
 
   // Check that overwriting change in overlay is reported.
-  overlay_->SetValue(overlay_key, new FundamentalValue(44));
+  overlay_->SetValue(overlay_key, new FundamentalValue(44),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(overlay_key);
 
   // Check that hidden underlay change is not reported.
-  underlay_->SetValue(overlay_key, new FundamentalValue(45));
+  underlay_->SetValue(overlay_key, new FundamentalValue(45),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 
   // Check that overlay remove is reported.
-  overlay_->RemoveValue(overlay_key);
+  overlay_->RemoveValue(overlay_key,
+                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(overlay_key);
 
   // Check that underlay remove is reported.
-  underlay_->RemoveValue(overlay_key);
+  underlay_->RemoveValue(overlay_key,
+                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(overlay_key);
 
   // Check respecting of silence.
-  overlay_->SetValueSilently(overlay_key, new FundamentalValue(46));
+  overlay_->SetValueSilently(overlay_key, new FundamentalValue(46),
+                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 
   overlay_->RemoveObserver(&obs);
 
   // Check successful unsubscription.
-  underlay_->SetValue(overlay_key, new FundamentalValue(47));
-  overlay_->SetValue(overlay_key, new FundamentalValue(48));
+  underlay_->SetValue(overlay_key, new FundamentalValue(47),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  overlay_->SetValue(overlay_key, new FundamentalValue(48),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 }
 
@@ -88,7 +97,8 @@
   EXPECT_FALSE(overlay_->GetValue(overlay_key, &value));
   EXPECT_FALSE(underlay_->GetValue(overlay_key, &value));
 
-  underlay_->SetValue(overlay_key, new FundamentalValue(42));
+  underlay_->SetValue(overlay_key, new FundamentalValue(42),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   // Value shines through:
   EXPECT_TRUE(overlay_->GetValue(overlay_key, &value));
@@ -97,7 +107,8 @@
   EXPECT_TRUE(underlay_->GetValue(overlay_key, &value));
   EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
 
-  overlay_->SetValue(overlay_key, new FundamentalValue(43));
+  overlay_->SetValue(overlay_key, new FundamentalValue(43),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   EXPECT_TRUE(overlay_->GetValue(overlay_key, &value));
   EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
@@ -105,7 +116,8 @@
   EXPECT_TRUE(underlay_->GetValue(overlay_key, &value));
   EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
 
-  overlay_->RemoveValue(overlay_key);
+  overlay_->RemoveValue(overlay_key,
+                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   // Value shines through:
   EXPECT_TRUE(overlay_->GetValue(overlay_key, &value));
@@ -117,7 +129,8 @@
 
 // Check that GetMutableValue does not return the dictionary of the underlay.
 TEST_F(OverlayUserPrefStoreTest, ModifyDictionaries) {
-  underlay_->SetValue(overlay_key, new DictionaryValue);
+  underlay_->SetValue(overlay_key, new DictionaryValue,
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   Value* modify = NULL;
   EXPECT_TRUE(overlay_->GetMutableValue(overlay_key, &modify));
@@ -146,11 +159,13 @@
   const Value* value = NULL;
 
   // Check that underlay first value is reported.
-  underlay_->SetValue(regular_key, new FundamentalValue(42));
+  underlay_->SetValue(regular_key, new FundamentalValue(42),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(regular_key);
 
   // Check that underlay overwriting is reported.
-  underlay_->SetValue(regular_key, new FundamentalValue(43));
+  underlay_->SetValue(regular_key, new FundamentalValue(43),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(regular_key);
 
   // Check that we get this value from the overlay
@@ -158,7 +173,8 @@
   EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
 
   // Check that overwriting change in overlay is reported.
-  overlay_->SetValue(regular_key, new FundamentalValue(44));
+  overlay_->SetValue(regular_key, new FundamentalValue(44),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(regular_key);
 
   // Check that we get this value from the overlay and the underlay.
@@ -168,7 +184,8 @@
   EXPECT_TRUE(base::FundamentalValue(44).Equals(value));
 
   // Check that overlay remove is reported.
-  overlay_->RemoveValue(regular_key);
+  overlay_->RemoveValue(regular_key,
+                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(regular_key);
 
   // Check that value was removed from overlay and underlay
@@ -176,14 +193,17 @@
   EXPECT_FALSE(underlay_->GetValue(regular_key, &value));
 
   // Check respecting of silence.
-  overlay_->SetValueSilently(regular_key, new FundamentalValue(46));
+  overlay_->SetValueSilently(regular_key, new FundamentalValue(46),
+                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 
   overlay_->RemoveObserver(&obs);
 
   // Check successful unsubscription.
-  underlay_->SetValue(regular_key, new FundamentalValue(47));
-  overlay_->SetValue(regular_key, new FundamentalValue(48));
+  underlay_->SetValue(regular_key, new FundamentalValue(47),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  overlay_->SetValue(regular_key, new FundamentalValue(48),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 }
 
@@ -196,11 +216,13 @@
 
   // Check that if there is no override in the overlay, changing underlay value
   // is reported as changing an overlay value.
-  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(42));
+  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(42),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(mapped_overlay_key);
 
   // Check that underlay overwriting is reported.
-  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(43));
+  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(43),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(mapped_overlay_key);
 
   // Check that we get this value from the overlay with both keys
@@ -211,7 +233,8 @@
   EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
 
   // Check that overwriting change in overlay is reported.
-  overlay_->SetValue(mapped_overlay_key, new FundamentalValue(44));
+  overlay_->SetValue(mapped_overlay_key, new FundamentalValue(44),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(mapped_overlay_key);
 
   // Check that we get an overriden value from overlay, while reading the
@@ -224,15 +247,18 @@
   EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
 
   // Check that hidden underlay change is not reported.
-  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(45));
+  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(45),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 
   // Check that overlay remove is reported.
-  overlay_->RemoveValue(mapped_overlay_key);
+  overlay_->RemoveValue(mapped_overlay_key,
+                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(mapped_overlay_key);
 
   // Check that underlay remove is reported.
-  underlay_->RemoveValue(mapped_underlay_key);
+  underlay_->RemoveValue(mapped_underlay_key,
+                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   obs.VerifyAndResetChangedKey(mapped_overlay_key);
 
   // Check that value was removed.
@@ -240,14 +266,17 @@
   EXPECT_FALSE(overlay_->GetValue(mapped_underlay_key, &value));
 
   // Check respecting of silence.
-  overlay_->SetValueSilently(mapped_overlay_key, new FundamentalValue(46));
+  overlay_->SetValueSilently(mapped_overlay_key, new FundamentalValue(46),
+                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 
   overlay_->RemoveObserver(&obs);
 
   // Check successful unsubscription.
-  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(47));
-  overlay_->SetValue(mapped_overlay_key, new FundamentalValue(48));
+  underlay_->SetValue(mapped_underlay_key, new FundamentalValue(47),
+                      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  overlay_->SetValue(mapped_overlay_key, new FundamentalValue(48),
+                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(obs.changed_keys.empty());
 }
 
diff --git a/base/prefs/pref_registry.h b/base/prefs/pref_registry.h
index cc5804e..caf2a1a 100644
--- a/base/prefs/pref_registry.h
+++ b/base/prefs/pref_registry.h
@@ -32,11 +32,15 @@
   // behave or be stored. This will be passed in a bitmask when the pref is
   // registered. Subclasses of PrefRegistry can specify their own flags. Care
   // must be taken to ensure none of these overlap with the flags below.
-  enum PrefRegistrationFlags {
+  enum PrefRegistrationFlags : uint32 {
     // No flags are specified.
     NO_REGISTRATION_FLAGS = 0,
 
     // The first 8 bits are reserved for subclasses of PrefRegistry to use.
+
+    // This marks the pref as "lossy". There is no strict time guarantee on when
+    // a lossy pref will be persisted to permanent storage when it is modified.
+    LOSSY_PREF = 1 << 8,
   };
 
   typedef PrefValueMap::const_iterator const_iterator;
diff --git a/base/prefs/pref_service.cc b/base/prefs/pref_service.cc
index 3ccdae7..6e1d58c 100644
--- a/base/prefs/pref_service.cc
+++ b/base/prefs/pref_service.cc
@@ -38,6 +38,19 @@
   base::Callback<void(PersistentPrefStore::PrefReadError)> callback_;
 };
 
+// Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
+// |path|.
+uint32 GetWriteFlags(const PrefService::Preference* pref) {
+  uint32 write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
+
+  if (!pref)
+    return write_flags;
+
+  if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
+    write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
+  return write_flags;
+}
+
 }  // namespace
 
 PrefService::PrefService(
@@ -177,8 +190,7 @@
   DCHECK(CalledOnValidThread());
   scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
   for (const auto& it : *pref_registry_) {
-    const base::Value* value = GetPreferenceValue(it.first);
-    out->Set(it.first, value->DeepCopy());
+    out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
   }
   return out.Pass();
 }
@@ -191,7 +203,7 @@
     const Preference* pref = FindPreference(it.first);
     if (pref->IsDefaultValue())
       continue;
-    out->Set(it.first, pref->GetValue()->DeepCopy());
+    out->Set(it.first, pref->GetValue()->CreateDeepCopy());
   }
   return out.Pass();
 }
@@ -203,7 +215,7 @@
   for (const auto& it : *pref_registry_) {
     const base::Value* value = GetPreferenceValue(it.first);
     DCHECK(value);
-    out->SetWithoutPathExpansion(it.first, value->DeepCopy());
+    out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
   }
   return out.Pass();
 }
@@ -357,7 +369,7 @@
     NOTREACHED() << "Trying to clear an unregistered pref: " << path;
     return;
   }
-  user_pref_store_->RemoveValue(path);
+  user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
 }
 
 void PrefService::Set(const std::string& path, const base::Value& value) {
@@ -454,14 +466,14 @@
     } else {
       NOTREACHED();
     }
-    user_pref_store_->SetValueSilently(path, value);
+    user_pref_store_->SetValueSilently(path, value, GetWriteFlags(pref));
   }
   return value;
 }
 
 void PrefService::ReportUserPrefChanged(const std::string& key) {
   DCHECK(CalledOnValidThread());
-  user_pref_store_->ReportValueChanged(key);
+  user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
 }
 
 void PrefService::SetUserPrefValue(const std::string& path,
@@ -481,7 +493,7 @@
     return;
   }
 
-  user_pref_store_->SetValue(path, owned_value.release());
+  user_pref_store_->SetValue(path, owned_value.release(), GetWriteFlags(pref));
 }
 
 void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
@@ -496,6 +508,9 @@
                                     base::Value::Type type)
     : name_(name), type_(type), pref_service_(service) {
   DCHECK(service);
+  // Cache the registration flags at creation time to avoid multiple map lookups
+  // later.
+  registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
 }
 
 const std::string PrefService::Preference::name() const {
diff --git a/base/prefs/pref_service.h b/base/prefs/pref_service.h
index d9b03c9..1fc6c12 100644
--- a/base/prefs/pref_service.h
+++ b/base/prefs/pref_service.h
@@ -128,6 +128,10 @@
     // the Preference.
     bool IsExtensionModifiable() const;
 
+    // Return the registration flags for this pref as a bitmask of
+    // PrefRegistry::PrefRegistrationFlags.
+    uint32 registration_flags() const { return registration_flags_; }
+
    private:
     friend class PrefService;
 
@@ -139,6 +143,8 @@
 
     const base::Value::Type type_;
 
+    uint32 registration_flags_;
+
     // Reference to the PrefService in which this pref was created.
     const PrefService* pref_service_;
   };
@@ -307,6 +313,7 @@
 
   // Give access to ReportUserPrefChanged() and GetMutableUserPref().
   friend class subtle::ScopedUserPrefUpdateBase;
+  friend class PrefServiceTest_WriteablePrefStoreFlags_Test;
 
   // Registration of pref change observers must be done using the
   // PrefChangeRegistrar, which is declared as a friend here to grant it
diff --git a/base/prefs/pref_service_unittest.cc b/base/prefs/pref_service_unittest.cc
index 36ad887..262d7e9 100644
--- a/base/prefs/pref_service_unittest.cc
+++ b/base/prefs/pref_service_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/prefs/mock_pref_change_callback.h"
 #include "base/prefs/pref_change_registrar.h"
 #include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service_factory.h"
 #include "base/prefs/pref_value_store.h"
 #include "base/prefs/testing_pref_service.h"
 #include "base/prefs/testing_pref_store.h"
@@ -227,6 +228,115 @@
   EXPECT_EQ(kRecommendedValue, actual_int_value);
 }
 
+// A PrefStore which just stores the last write flags that were used to write
+// values to it.
+class WriteFlagChecker : public TestingPrefStore {
+ public:
+  WriteFlagChecker() {}
+
+  void ReportValueChanged(const std::string& key, uint32 flags) override {
+    SetLastWriteFlags(flags);
+  }
+
+  void SetValue(const std::string& key,
+                base::Value* value,
+                uint32 flags) override {
+    SetLastWriteFlags(flags);
+    delete value;
+  }
+
+  void SetValueSilently(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) override {
+    SetLastWriteFlags(flags);
+    delete value;
+  }
+
+  void RemoveValue(const std::string& key, uint32 flags) override {
+    SetLastWriteFlags(flags);
+  }
+
+  uint32 GetLastFlagsAndClear() {
+    CHECK(last_write_flags_set_);
+    uint32 result = last_write_flags_;
+    last_write_flags_set_ = false;
+    last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
+    return result;
+  }
+
+  bool last_write_flags_set() { return last_write_flags_set_; }
+
+ private:
+  ~WriteFlagChecker() override {}
+
+  void SetLastWriteFlags(uint32 flags) {
+    CHECK(!last_write_flags_set_);
+    last_write_flags_set_ = true;
+    last_write_flags_ = flags;
+  }
+
+  bool last_write_flags_set_ = false;
+  uint32 last_write_flags_ = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
+};
+
+TEST(PrefServiceTest, WriteablePrefStoreFlags) {
+  scoped_refptr<WriteFlagChecker> flag_checker(new WriteFlagChecker);
+  scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple);
+  base::PrefServiceFactory factory;
+  factory.set_user_prefs(flag_checker);
+  scoped_ptr<PrefService> prefs(factory.Create(registry.get()));
+
+  // The first 8 bits of write flags are reserved for subclasses. Create a
+  // custom flag in this range
+  uint32 kCustomRegistrationFlag = 1 << 2;
+
+  // A map of the registration flags that will be tested and the write flags
+  // they are expected to convert to.
+  struct RegistrationToWriteFlags {
+    const char* pref_name;
+    uint32 registration_flags;
+    uint32 write_flags;
+  };
+  const RegistrationToWriteFlags kRegistrationToWriteFlags[] = {
+      {"none",
+       PrefRegistry::NO_REGISTRATION_FLAGS,
+       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS},
+      {"lossy",
+       PrefRegistry::LOSSY_PREF,
+       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG},
+      {"custom",
+       kCustomRegistrationFlag,
+       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS},
+      {"lossyandcustom",
+       PrefRegistry::LOSSY_PREF | kCustomRegistrationFlag,
+       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG}};
+
+  for (size_t i = 0; i < arraysize(kRegistrationToWriteFlags); ++i) {
+    RegistrationToWriteFlags entry = kRegistrationToWriteFlags[i];
+    registry->RegisterDictionaryPref(
+        entry.pref_name, new base::DictionaryValue(), entry.registration_flags);
+
+    SCOPED_TRACE("Currently testing pref with name: " +
+                 std::string(entry.pref_name));
+
+    prefs->GetMutableUserPref(entry.pref_name, base::Value::TYPE_DICTIONARY);
+    EXPECT_TRUE(flag_checker->last_write_flags_set());
+    EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
+
+    prefs->ReportUserPrefChanged(entry.pref_name);
+    EXPECT_TRUE(flag_checker->last_write_flags_set());
+    EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
+
+    prefs->ClearPref(entry.pref_name);
+    EXPECT_TRUE(flag_checker->last_write_flags_set());
+    EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
+
+    prefs->SetUserPrefValue(entry.pref_name, new base::DictionaryValue());
+    EXPECT_TRUE(flag_checker->last_write_flags_set());
+    EXPECT_EQ(entry.write_flags, flag_checker->GetLastFlagsAndClear());
+  }
+}
+
 class PrefServiceSetValueTest : public testing::Test {
  protected:
   static const char kName[];
diff --git a/base/prefs/testing_pref_service.h b/base/prefs/testing_pref_service.h
index 40fd66a..7587383 100644
--- a/base/prefs/testing_pref_service.h
+++ b/base/prefs/testing_pref_service.h
@@ -182,13 +182,14 @@
     SetPref(TestingPrefStore* pref_store,
             const std::string& path,
             base::Value* value) {
-  pref_store->SetValue(path, value);
+  pref_store->SetValue(path, value,
+                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 }
 
 template <class SuperPrefService, class ConstructionPrefRegistry>
 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
     RemovePref(TestingPrefStore* pref_store, const std::string& path) {
-  pref_store->RemoveValue(path);
+  pref_store->RemoveValue(path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 }
 
 #endif  // BASE_PREFS_TESTING_PREF_SERVICE_H_
diff --git a/base/prefs/testing_pref_store.cc b/base/prefs/testing_pref_store.cc
index f20824e..35c9763 100644
--- a/base/prefs/testing_pref_store.cc
+++ b/base/prefs/testing_pref_store.cc
@@ -42,7 +42,9 @@
   return init_complete_;
 }
 
-void TestingPrefStore::SetValue(const std::string& key, base::Value* value) {
+void TestingPrefStore::SetValue(const std::string& key,
+                                base::Value* value,
+                                uint32 flags) {
   if (prefs_.SetValue(key, value)) {
     committed_ = false;
     NotifyPrefValueChanged(key);
@@ -50,12 +52,13 @@
 }
 
 void TestingPrefStore::SetValueSilently(const std::string& key,
-                                        base::Value* value) {
+                                        base::Value* value,
+                                        uint32 flags) {
   if (prefs_.SetValue(key, value))
     committed_ = false;
 }
 
-void TestingPrefStore::RemoveValue(const std::string& key) {
+void TestingPrefStore::RemoveValue(const std::string& key, uint32 flags) {
   if (prefs_.RemoveValue(key)) {
     committed_ = false;
     NotifyPrefValueChanged(key);
@@ -103,21 +106,22 @@
       Observer, observers_, OnInitializationCompleted(read_success_));
 }
 
-void TestingPrefStore::ReportValueChanged(const std::string& key) {
+void TestingPrefStore::ReportValueChanged(const std::string& key,
+                                          uint32 flags) {
   FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
 }
 
 void TestingPrefStore::SetString(const std::string& key,
                                  const std::string& value) {
-  SetValue(key, new base::StringValue(value));
+  SetValue(key, new base::StringValue(value), DEFAULT_PREF_WRITE_FLAGS);
 }
 
 void TestingPrefStore::SetInteger(const std::string& key, int value) {
-  SetValue(key, new base::FundamentalValue(value));
+  SetValue(key, new base::FundamentalValue(value), DEFAULT_PREF_WRITE_FLAGS);
 }
 
 void TestingPrefStore::SetBoolean(const std::string& key, bool value) {
-  SetValue(key, new base::FundamentalValue(value));
+  SetValue(key, new base::FundamentalValue(value), DEFAULT_PREF_WRITE_FLAGS);
 }
 
 bool TestingPrefStore::GetString(const std::string& key,
diff --git a/base/prefs/testing_pref_store.h b/base/prefs/testing_pref_store.h
index 866b4ae..3de5cac 100644
--- a/base/prefs/testing_pref_store.h
+++ b/base/prefs/testing_pref_store.h
@@ -30,10 +30,14 @@
 
   // PersistentPrefStore overrides:
   bool GetMutableValue(const std::string& key, base::Value** result) override;
-  void ReportValueChanged(const std::string& key) override;
-  void SetValue(const std::string& key, base::Value* value) override;
-  void SetValueSilently(const std::string& key, base::Value* value) override;
-  void RemoveValue(const std::string& key) override;
+  void ReportValueChanged(const std::string& key, uint32 flags) override;
+  void SetValue(const std::string& key,
+                base::Value* value,
+                uint32 flags) override;
+  void SetValueSilently(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) override;
+  void RemoveValue(const std::string& key, uint32 flags) override;
   bool ReadOnly() const override;
   PrefReadError GetReadError() const override;
   PersistentPrefStore::PrefReadError ReadPrefs() override;
diff --git a/base/prefs/value_map_pref_store.cc b/base/prefs/value_map_pref_store.cc
index 8af1282..d850150 100644
--- a/base/prefs/value_map_pref_store.cc
+++ b/base/prefs/value_map_pref_store.cc
@@ -28,12 +28,14 @@
   return observers_.might_have_observers();
 }
 
-void ValueMapPrefStore::SetValue(const std::string& key, base::Value* value) {
+void ValueMapPrefStore::SetValue(const std::string& key,
+                                 base::Value* value,
+                                 uint32 flags) {
   if (prefs_.SetValue(key, value))
     FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
 }
 
-void ValueMapPrefStore::RemoveValue(const std::string& key) {
+void ValueMapPrefStore::RemoveValue(const std::string& key, uint32 flags) {
   if (prefs_.RemoveValue(key))
     FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
 }
@@ -43,12 +45,14 @@
   return prefs_.GetValue(key, value);
 }
 
-void ValueMapPrefStore::ReportValueChanged(const std::string& key) {
+void ValueMapPrefStore::ReportValueChanged(const std::string& key,
+                                           uint32 flags) {
   FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
 }
 
 void ValueMapPrefStore::SetValueSilently(const std::string& key,
-                                         base::Value* value) {
+                                         base::Value* value,
+                                         uint32 flags) {
   prefs_.SetValue(key, value);
 }
 
diff --git a/base/prefs/value_map_pref_store.h b/base/prefs/value_map_pref_store.h
index 8c515ed..86c94bb 100644
--- a/base/prefs/value_map_pref_store.h
+++ b/base/prefs/value_map_pref_store.h
@@ -28,11 +28,15 @@
   bool HasObservers() const override;
 
   // WriteablePrefStore overrides:
-  void SetValue(const std::string& key, base::Value* value) override;
-  void RemoveValue(const std::string& key) override;
+  void SetValue(const std::string& key,
+                base::Value* value,
+                uint32 flags) override;
+  void RemoveValue(const std::string& key, uint32 flags) override;
   bool GetMutableValue(const std::string& key, base::Value** value) override;
-  void ReportValueChanged(const std::string& key) override;
-  void SetValueSilently(const std::string& key, base::Value* value) override;
+  void ReportValueChanged(const std::string& key, uint32 flags) override;
+  void SetValueSilently(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) override;
 
  protected:
   ~ValueMapPrefStore() override;
diff --git a/base/prefs/writeable_pref_store.h b/base/prefs/writeable_pref_store.h
index 5ebab64..d85b4c8 100644
--- a/base/prefs/writeable_pref_store.h
+++ b/base/prefs/writeable_pref_store.h
@@ -17,14 +17,27 @@
 // A pref store that can be written to as well as read from.
 class BASE_PREFS_EXPORT WriteablePrefStore : public PrefStore {
  public:
+  // PrefWriteFlags can be used to change the way a pref will be written to
+  // storage.
+  enum PrefWriteFlags : uint32 {
+    // No flags are specified.
+    DEFAULT_PREF_WRITE_FLAGS = 0,
+
+    // This marks the pref as "lossy". There is no strict time guarantee on when
+    // a lossy pref will be persisted to permanent storage when it is modified.
+    LOSSY_PREF_WRITE_FLAG = 1 << 1
+  };
+
   WriteablePrefStore() {}
 
   // Sets a |value| for |key| in the store. Assumes ownership of |value|, which
-  // must be non-NULL.
-  virtual void SetValue(const std::string& key, base::Value* value) = 0;
+  // must be non-NULL. |flags| is a bitmask of PrefWriteFlags.
+  virtual void SetValue(const std::string& key,
+                        base::Value* value,
+                        uint32 flags) = 0;
 
   // Removes the value for |key|.
-  virtual void RemoveValue(const std::string& key) = 0;
+  virtual void RemoveValue(const std::string& key, uint32 flags) = 0;
 
   // Equivalent to PrefStore::GetValue but returns a mutable value.
   virtual bool GetMutableValue(const std::string& key,
@@ -34,13 +47,17 @@
   // if one retrieves a list or dictionary with GetMutableValue and change its
   // value. SetValue takes care of notifications itself. Note that
   // ReportValueChanged will trigger notifications even if nothing has changed.
-  virtual void ReportValueChanged(const std::string& key) = 0;
+  // |flags| is a bitmask of PrefWriteFlags.
+  virtual void ReportValueChanged(const std::string& key, uint32 flags) = 0;
 
   // Same as SetValue, but doesn't generate notifications. This is used by
   // PrefService::GetMutableUserPref() in order to put empty entries
   // into the user pref store. Using SetValue is not an option since existing
-  // tests rely on the number of notifications generated.
-  virtual void SetValueSilently(const std::string& key, base::Value* value) = 0;
+  // tests rely on the number of notifications generated. |flags| is a bitmask
+  // of PrefWriteFlags.
+  virtual void SetValueSilently(const std::string& key,
+                                base::Value* value,
+                                uint32 flags) = 0;
 
  protected:
   ~WriteablePrefStore() override {}
diff --git a/base/process/process_metrics.cc b/base/process/process_metrics.cc
index 2edd9c7..e486339 100644
--- a/base/process/process_metrics.cc
+++ b/base/process/process_metrics.cc
@@ -33,11 +33,11 @@
 
   res->SetInteger("committed_memory", static_cast<int>(committed_memory_));
 #if defined(OS_LINUX) || defined(OS_ANDROID)
-  res->Set("meminfo", memory_info_.ToValue().release());
-  res->Set("diskinfo", disk_info_.ToValue().release());
+  res->Set("meminfo", memory_info_.ToValue());
+  res->Set("diskinfo", disk_info_.ToValue());
 #endif
 #if defined(OS_CHROMEOS)
-  res->Set("swapinfo", swap_info_.ToValue().release());
+  res->Set("swapinfo", swap_info_.ToValue());
 #endif
 
   return res.Pass();
diff --git a/base/profiler/scoped_profile.h b/base/profiler/scoped_profile.h
index 6b0c800..2c4105d 100644
--- a/base/profiler/scoped_profile.h
+++ b/base/profiler/scoped_profile.h
@@ -62,4 +62,4 @@
 
 }  // namespace tracked_objects
 
-#endif   // BASE_PROFILER_SCOPED_PROFILE_H_
+#endif  // BASE_PROFILER_SCOPED_PROFILE_H_
diff --git a/base/profiler/tracked_time_unittest.cc b/base/profiler/tracked_time_unittest.cc
index 4806a90..c105688 100644
--- a/base/profiler/tracked_time_unittest.cc
+++ b/base/profiler/tracked_time_unittest.cc
@@ -70,16 +70,14 @@
 TEST(TrackedTimeTest, TrackedTimerDisabled) {
   // Check to be sure disabling the collection of data induces a null time
   // (which we know will return much faster).
-  if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED))
-    return;
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED);
   // Since we disabled tracking, we should get a null response.
   TrackedTime track_now = ThreadData::Now();
   EXPECT_TRUE(track_now.is_null());
 }
 
 TEST(TrackedTimeTest, TrackedTimerEnabled) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE))
-    return;
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
   // Make sure that when we enable tracking, we get a real timer result.
 
   // First get a 64 bit timer (which should not be null).
diff --git a/base/sys_info.cc b/base/sys_info.cc
index 72a9944..8640dc1 100644
--- a/base/sys_info.cc
+++ b/base/sys_info.cc
@@ -7,7 +7,9 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
+#include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/sys_info_internal.h"
 #include "base/time/time.h"
 
@@ -34,6 +36,14 @@
 
 // static
 bool SysInfo::IsLowEndDevice() {
+  const std::string group_name =
+      base::FieldTrialList::FindFullName("MemoryReduction");
+
+  // Low End Device Mode will be enabled if this client is assigned to
+  // one of those EnabledXXX groups.
+  if (StartsWithASCII(group_name, "Enabled", true))
+    return true;
+
   return g_lazy_low_end_device.Get().value();
 }
 #endif
diff --git a/base/test/launcher/test_results_tracker.cc b/base/test/launcher/test_results_tracker.cc
index b553fd6..c4cb233 100644
--- a/base/test/launcher/test_results_tracker.cc
+++ b/base/test/launcher/test_results_tracker.cc
@@ -239,52 +239,39 @@
 bool TestResultsTracker::SaveSummaryAsJSON(const FilePath& path) const {
   scoped_ptr<DictionaryValue> summary_root(new DictionaryValue);
 
-  ListValue* global_tags = new ListValue;
-  summary_root->Set("global_tags", global_tags);
-
-  for (std::set<std::string>::const_iterator i = global_tags_.begin();
-       i != global_tags_.end();
-       ++i) {
-    global_tags->AppendString(*i);
+  scoped_ptr<ListValue> global_tags(new ListValue);
+  for (const auto& global_tag : global_tags_) {
+    global_tags->AppendString(global_tag);
   }
+  summary_root->Set("global_tags", global_tags.Pass());
 
-  ListValue* all_tests = new ListValue;
-  summary_root->Set("all_tests", all_tests);
-
-  for (std::set<std::string>::const_iterator i = all_tests_.begin();
-       i != all_tests_.end();
-       ++i) {
-    all_tests->AppendString(*i);
+  scoped_ptr<ListValue> all_tests(new ListValue);
+  for (const auto& test : all_tests_) {
+    all_tests->AppendString(test);
   }
+  summary_root->Set("all_tests", all_tests.Pass());
 
-  ListValue* disabled_tests = new ListValue;
-  summary_root->Set("disabled_tests", disabled_tests);
-
-  for (std::set<std::string>::const_iterator i = disabled_tests_.begin();
-       i != disabled_tests_.end();
-       ++i) {
-    disabled_tests->AppendString(*i);
+  scoped_ptr<ListValue> disabled_tests(new ListValue);
+  for (const auto& disabled_test : disabled_tests_) {
+    disabled_tests->AppendString(disabled_test);
   }
+  summary_root->Set("disabled_tests", disabled_tests.Pass());
 
-  ListValue* per_iteration_data = new ListValue;
-  summary_root->Set("per_iteration_data", per_iteration_data);
+  scoped_ptr<ListValue> per_iteration_data(new ListValue);
 
   for (int i = 0; i <= iteration_; i++) {
-    DictionaryValue* current_iteration_data = new DictionaryValue;
-    per_iteration_data->Append(current_iteration_data);
+    scoped_ptr<DictionaryValue> current_iteration_data(new DictionaryValue);
 
     for (PerIterationData::ResultsMap::const_iterator j =
              per_iteration_data_[i].results.begin();
          j != per_iteration_data_[i].results.end();
          ++j) {
-      ListValue* test_results = new ListValue;
-      current_iteration_data->SetWithoutPathExpansion(j->first, test_results);
+      scoped_ptr<ListValue> test_results(new ListValue);
 
       for (size_t k = 0; k < j->second.test_results.size(); k++) {
         const TestResult& test_result = j->second.test_results[k];
 
-        DictionaryValue* test_result_value = new DictionaryValue;
-        test_results->Append(test_result_value);
+        scoped_ptr<DictionaryValue> test_result_value(new DictionaryValue);
 
         test_result_value->SetString("status", test_result.StatusAsString());
         test_result_value->SetInteger(
@@ -310,8 +297,14 @@
         Base64Encode(test_result.output_snippet, &base64_output_snippet);
         test_result_value->SetString("output_snippet_base64",
                                      base64_output_snippet);
+        test_results->Append(test_result_value.Pass());
       }
+
+      current_iteration_data->SetWithoutPathExpansion(j->first,
+                                                      test_results.Pass());
     }
+    per_iteration_data->Append(current_iteration_data.Pass());
+    summary_root->Set("per_iteration_data", per_iteration_data.Pass());
   }
 
   JSONFileValueSerializer serializer(path);
diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc
index 4bdb941..cf85fd0 100644
--- a/base/test/trace_event_analyzer_unittest.cc
+++ b/base/test/trace_event_analyzer_unittest.cc
@@ -225,7 +225,7 @@
 
   scoped_ptr<TraceAnalyzer>
       analyzer(TraceAnalyzer::Create(output_.json_output));
-  ASSERT_TRUE(!!analyzer.get());
+  ASSERT_TRUE(analyzer);
   analyzer->SetIgnoreMetadataEvents(true);
 
   TraceEventVector found;
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index c5dfd79..3e762b9 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -69,7 +69,7 @@
       NULL, &error_msg));
   if (!result) {
     ADD_FAILURE() << "Failed to parse \"" << json << "\": " << error_msg;
-    result.reset(Value::CreateNullValue());
+    result = Value::CreateNullValue();
   }
   return result.Pass();
 }
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index 69a2b0d..d8f06e5 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -89,10 +89,6 @@
         id_(id) {
   }
 
-  PlatformThreadId id() const {
-    return id_;
-  }
-
   bool is_equal(const PlatformThreadHandle& other) const {
     return handle_ == other.handle_;
   }
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
index aeaa7c7..4eb2cb2 100644
--- a/base/threading/platform_thread_win.cc
+++ b/base/threading/platform_thread_win.cc
@@ -108,16 +108,15 @@
   // have to work running on CreateThread() threads anyway, since we run code
   // on the Windows thread pool, etc.  For some background on the difference:
   //   http://www.microsoft.com/msj/1099/win32/win321099.aspx
-  PlatformThreadId thread_id;
   void* thread_handle = CreateThread(
-      NULL, stack_size, ThreadFunc, params, flags, &thread_id);
+      NULL, stack_size, ThreadFunc, params, flags, NULL);
   if (!thread_handle) {
     delete params;
     return false;
   }
 
   if (out_thread_handle)
-    *out_thread_handle = PlatformThreadHandle(thread_handle, thread_id);
+    *out_thread_handle = PlatformThreadHandle(thread_handle);
   else
     CloseHandle(thread_handle);
   return true;
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index bd565c9..0e4aab2 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -37,6 +37,20 @@
   Thread::SetThreadWasQuitProperly(true);
 }
 
+// Used to pass data to ThreadMain.  This structure is allocated on the stack
+// from within StartWithOptions.
+struct Thread::StartupData {
+  // We get away with a const reference here because of how we are allocated.
+  const Thread::Options& options;
+
+  // Used to synchronize thread startup.
+  WaitableEvent event;
+
+  explicit StartupData(const Options& opt)
+      : options(opt),
+        event(false, false) {}
+};
+
 Thread::Options::Options()
     : message_loop_type(MessageLoop::TYPE_DEFAULT),
       timer_slack(TIMER_SLACK_NONE),
@@ -58,11 +72,13 @@
 #if defined(OS_WIN)
       com_status_(NONE),
 #endif
+      started_(false),
       stopping_(false),
       running_(false),
+      startup_data_(NULL),
       thread_(0),
-      message_loop_(nullptr),
-      message_loop_timer_slack_(TIMER_SLACK_NONE),
+      message_loop_(NULL),
+      thread_id_(kInvalidThreadId),
       name_(name) {
 }
 
@@ -88,45 +104,34 @@
 
   SetThreadWasQuitProperly(false);
 
-  MessageLoop::Type type = options.message_loop_type;
-  if (!options.message_pump_factory.is_null())
-    type = MessageLoop::TYPE_CUSTOM;
-
-  message_loop_timer_slack_ = options.timer_slack;
-  message_loop_ = new MessageLoop(type, options.message_pump_factory);
-
-  start_event_.reset(new WaitableEvent(false, false));
+  StartupData startup_data(options);
+  startup_data_ = &startup_data;
 
   if (!PlatformThread::Create(options.stack_size, this, &thread_)) {
     DLOG(ERROR) << "failed to create thread";
-    delete message_loop_;
-    message_loop_ = nullptr;
-    start_event_.reset();
+    startup_data_ = NULL;
     return false;
   }
 
+  // TODO(kinuko): Remove once crbug.com/465458 is solved.
+  tracked_objects::ScopedTracker tracking_profile_wait(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "465458 base::Thread::StartWithOptions (Wait)"));
+
+  // Wait for the thread to start and initialize message_loop_
+  base::ThreadRestrictions::ScopedAllowWait allow_wait;
+  startup_data.event.Wait();
+
+  // set it to NULL so we don't keep a pointer to some object on the stack.
+  startup_data_ = NULL;
+  started_ = true;
+
   DCHECK(message_loop_);
   return true;
 }
 
-bool Thread::StartAndWaitForTesting() {
-  bool result = Start();
-  if (!result)
-    return false;
-  WaitUntilThreadStarted();
-  return result;
-}
-
-bool Thread::WaitUntilThreadStarted() {
-  if (!start_event_)
-    return false;
-  base::ThreadRestrictions::ScopedAllowWait allow_wait;
-  start_event_->Wait();
-  return true;
-}
-
 void Thread::Stop() {
-  if (!start_event_)
+  if (!started_)
     return;
 
   StopSoon();
@@ -142,7 +147,7 @@
   DCHECK(!message_loop_);
 
   // The thread no longer needs to be joined.
-  start_event_.reset();
+  started_ = false;
 
   stopping_ = false;
 }
@@ -150,7 +155,9 @@
 void Thread::StopSoon() {
   // We should only be called on the same thread that started us.
 
-  DCHECK_NE(thread_id(), PlatformThread::CurrentId());
+  // Reading thread_id_ without a lock can lead to a benign data race
+  // with ThreadMain, so we annotate it to stay silent under ThreadSanitizer.
+  DCHECK_NE(ANNOTATE_UNPROTECTED_READ(thread_id_), PlatformThread::CurrentId());
 
   if (stopping_ || !message_loop_)
     return;
@@ -160,22 +167,13 @@
 }
 
 bool Thread::IsRunning() const {
-  // If the thread's already started (i.e. message_loop_ is non-null) and
-  // not yet requested to stop (i.e. stopping_ is false) we can just return
-  // true. (Note that stopping_ is touched only on the same thread that
-  // starts / started the new thread so we need no locking here.)
-  if (message_loop_ && !stopping_)
-    return true;
-  // Otherwise check the running_ flag, which is set to true by the new thread
-  // only while it is inside Run().
-  AutoLock lock(lock_);
   return running_;
 }
 
 void Thread::SetPriority(ThreadPriority priority) {
   // The thread must be started (and id known) for this to be
   // compatible with all platforms.
-  DCHECK(message_loop_ != nullptr);
+  DCHECK_NE(thread_id_, kInvalidThreadId);
   PlatformThread::SetThreadPriority(thread_, priority);
 }
 
@@ -196,57 +194,60 @@
 }
 
 void Thread::ThreadMain() {
-  // Complete the initialization of our Thread object.
-  DCHECK_EQ(thread_id(), PlatformThread::CurrentId());
-  PlatformThread::SetName(name_.c_str());
-  ANNOTATE_THREAD_NAME(name_.c_str());  // Tell the name to race detector.
+  {
+    // The message loop for this thread.
+    // Allocated on the heap to centralize any leak reports at this line.
+    scoped_ptr<MessageLoop> message_loop;
+    if (!startup_data_->options.message_pump_factory.is_null()) {
+      message_loop.reset(
+          new MessageLoop(startup_data_->options.message_pump_factory.Run()));
+    } else {
+      message_loop.reset(
+          new MessageLoop(startup_data_->options.message_loop_type));
+    }
 
-  // Lazily initialize the message_loop so that it can run on this thread.
-  DCHECK(message_loop_);
-  scoped_ptr<MessageLoop> message_loop(message_loop_);
-  message_loop_->BindToCurrentThread();
-  message_loop_->set_thread_name(name_);
-  message_loop_->SetTimerSlack(message_loop_timer_slack_);
+    // Complete the initialization of our Thread object.
+    thread_id_ = PlatformThread::CurrentId();
+    PlatformThread::SetName(name_);
+    ANNOTATE_THREAD_NAME(name_.c_str());  // Tell the name to race detector.
+    message_loop->set_thread_name(name_);
+    message_loop->SetTimerSlack(startup_data_->options.timer_slack);
+    message_loop_ = message_loop.get();
 
 #if defined(OS_WIN)
-  scoped_ptr<win::ScopedCOMInitializer> com_initializer;
-  if (com_status_ != NONE) {
-    com_initializer.reset((com_status_ == STA) ?
-        new win::ScopedCOMInitializer() :
-        new win::ScopedCOMInitializer(win::ScopedCOMInitializer::kMTA));
-  }
+    scoped_ptr<win::ScopedCOMInitializer> com_initializer;
+    if (com_status_ != NONE) {
+      com_initializer.reset((com_status_ == STA) ?
+          new win::ScopedCOMInitializer() :
+          new win::ScopedCOMInitializer(win::ScopedCOMInitializer::kMTA));
+    }
 #endif
 
-  // Let the thread do extra initialization.
-  Init();
+    // Let the thread do extra initialization.
+    // Let's do this before signaling we are started.
+    Init();
 
-  {
-    AutoLock lock(lock_);
     running_ = true;
-  }
+    startup_data_->event.Signal();
+    // startup_data_ can't be touched anymore since the starting thread is now
+    // unlocked.
 
-  start_event_->Signal();
-
-  Run(message_loop_);
-
-  {
-    AutoLock lock(lock_);
+    Run(message_loop_);
     running_ = false;
-  }
 
-  // Let the thread do extra cleanup.
-  CleanUp();
+    // Let the thread do extra cleanup.
+    CleanUp();
 
 #if defined(OS_WIN)
-  com_initializer.reset();
+    com_initializer.reset();
 #endif
 
-  // Assert that MessageLoop::Quit was called by ThreadQuitHelper.
-  DCHECK(GetThreadWasQuitProperly());
+    // Assert that MessageLoop::Quit was called by ThreadQuitHelper.
+    DCHECK(GetThreadWasQuitProperly());
 
-  // We can't receive messages anymore.
-  // (The message loop is destructed at the end of this block)
-  message_loop_ = NULL;
+    // We can't receive messages anymore.
+    message_loop_ = NULL;
+  }
 }
 
 }  // namespace base
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 2e19b0a..4915606 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -13,13 +13,11 @@
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
 #include "base/threading/platform_thread.h"
 
 namespace base {
 
 class MessagePump;
-class WaitableEvent;
 
 // A simple thread abstraction that establishes a MessageLoop on a new thread.
 // The consumer uses the MessageLoop of the thread to cause code to execute on
@@ -47,7 +45,7 @@
     // This is ignored if message_pump_factory.is_null() is false.
     MessageLoop::Type message_loop_type;
 
-    // Specifies timer slack for thread message loop.
+    // Specify timer slack for thread message loop.
     TimerSlack timer_slack;
 
     // Used to create the MessagePump for the MessageLoop. The callback is Run()
@@ -83,7 +81,7 @@
   // init_com_with_mta(false) and then StartWithOptions() with any message loop
   // type other than TYPE_UI.
   void init_com_with_mta(bool use_mta) {
-    DCHECK(!start_event_);
+    DCHECK(!started_);
     com_status_ = use_mta ? MTA : STA;
   }
 #endif
@@ -105,18 +103,6 @@
   // callback.
   bool StartWithOptions(const Options& options);
 
-  // Starts the thread and wait for the thread to start and run initialization
-  // before returning. It's same as calling Start() and then
-  // WaitUntilThreadStarted().
-  // Note that using this (instead of Start() or StartWithOptions() causes
-  // jank on the calling thread, should be used only in testing code.
-  bool StartAndWaitForTesting();
-
-  // Blocks until the thread starts running. Called within StartAndWait().
-  // Note that calling this causes jank on the calling thread, must be used
-  // carefully for production code.
-  bool WaitUntilThreadStarted();
-
   // Signals the thread to exit and returns once the thread has exited.  After
   // this method returns, the Thread object is completely reset and may be used
   // as if it were newly constructed (i.e., Start may be called again).
@@ -180,7 +166,7 @@
   PlatformThreadHandle thread_handle() { return thread_; }
 
   // The thread ID.
-  PlatformThreadId thread_id() const { return thread_.id(); }
+  PlatformThreadId thread_id() const { return thread_id_; }
 
   // Returns true if the thread has been started, and not yet stopped.
   bool IsRunning() const;
@@ -222,13 +208,19 @@
   ComStatus com_status_;
 #endif
 
+  // Whether we successfully started the thread.
+  bool started_;
+
   // If true, we're in the middle of stopping, and shouldn't access
   // |message_loop_|. It may non-NULL and invalid.
   bool stopping_;
 
   // True while inside of Run().
   bool running_;
-  mutable base::Lock lock_;  // Protects running_.
+
+  // Used to pass data to ThreadMain.
+  struct StartupData;
+  StartupData* startup_data_;
 
   // The thread's handle.
   PlatformThreadHandle thread_;
@@ -237,16 +229,12 @@
   // by the created thread.
   MessageLoop* message_loop_;
 
-  // Stores Options::timer_slack_ until the message loop has been bound to
-  // a thread.
-  TimerSlack message_loop_timer_slack_;
+  // Our thread's ID.
+  PlatformThreadId thread_id_;
 
   // The name of the thread.  Used for debugging purposes.
   std::string name_;
 
-  // Non-null if the thread has successfully started.
-  scoped_ptr<WaitableEvent> start_event_;
-
   friend void ThreadQuitHelper();
 
   DISALLOW_COPY_AND_ASSIGN(Thread);
diff --git a/base/threading/thread_id_name_manager_unittest.cc b/base/threading/thread_id_name_manager_unittest.cc
index b17c681..b5953d5 100644
--- a/base/threading/thread_id_name_manager_unittest.cc
+++ b/base/threading/thread_id_name_manager_unittest.cc
@@ -21,8 +21,8 @@
   base::Thread thread_a(kAThread);
   base::Thread thread_b(kBThread);
 
-  thread_a.StartAndWaitForTesting();
-  thread_b.StartAndWaitForTesting();
+  thread_a.Start();
+  thread_b.Start();
 
   EXPECT_STREQ(kAThread, manager->GetName(thread_a.thread_id()));
   EXPECT_STREQ(kBThread, manager->GetName(thread_b.thread_id()));
@@ -35,10 +35,10 @@
   base::ThreadIdNameManager* manager = base::ThreadIdNameManager::GetInstance();
   base::Thread thread_a(kAThread);
 
-  thread_a.StartAndWaitForTesting();
+  thread_a.Start();
   {
     base::Thread thread_b(kBThread);
-    thread_b.StartAndWaitForTesting();
+    thread_b.Start();
     thread_b.Stop();
   }
   EXPECT_STREQ(kAThread, manager->GetName(thread_a.thread_id()));
@@ -51,12 +51,12 @@
   base::ThreadIdNameManager* manager = base::ThreadIdNameManager::GetInstance();
   base::Thread thread_a(kAThread);
 
-  thread_a.StartAndWaitForTesting();
+  thread_a.Start();
   base::PlatformThreadId a_id = thread_a.thread_id();
   EXPECT_STREQ(kAThread, manager->GetName(a_id));
   thread_a.Stop();
 
-  thread_a.StartAndWaitForTesting();
+  thread_a.Start();
   EXPECT_STREQ("", manager->GetName(a_id));
   EXPECT_STREQ(kAThread, manager->GetName(thread_a.thread_id()));
   thread_a.Stop();
diff --git a/base/threading/thread_local_android.cc b/base/threading/thread_local_android.cc
index c890237..813dd78 100644
--- a/base/threading/thread_local_android.cc
+++ b/base/threading/thread_local_android.cc
@@ -4,15 +4,12 @@
 
 #include "base/threading/thread_local.h"
 
-#include "base/logging.h"
-
 namespace base {
 namespace internal {
 
 // static
 void ThreadLocalPlatform::AllocateSlot(SlotType* slot) {
-  bool succeed = slot->Initialize(NULL);
-  CHECK(succeed);
+  slot->Initialize(nullptr);
 }
 
 // static
diff --git a/base/threading/thread_local_storage.cc b/base/threading/thread_local_storage.cc
index 54928ed..0bb396c 100644
--- a/base/threading/thread_local_storage.cc
+++ b/base/threading/thread_local_storage.cc
@@ -197,7 +197,7 @@
   Initialize(destructor);
 }
 
-bool ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) {
+void ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) {
   PlatformThreadLocalStorage::TLSKey key =
       base::subtle::NoBarrier_Load(&g_native_tls_key);
   if (key == PlatformThreadLocalStorage::TLS_KEY_OUT_OF_INDEXES ||
@@ -212,7 +212,6 @@
   // Setup our destructor.
   g_tls_destructors[slot_] = destructor;
   initialized_ = true;
-  return true;
 }
 
 void ThreadLocalStorage::StaticSlot::Free() {
diff --git a/base/threading/thread_local_storage.h b/base/threading/thread_local_storage.h
index ea41b34..50f8868 100644
--- a/base/threading/thread_local_storage.h
+++ b/base/threading/thread_local_storage.h
@@ -98,8 +98,7 @@
     // Set up the TLS slot.  Called by the constructor.
     // 'destructor' is a pointer to a function to perform per-thread cleanup of
     // this object.  If set to NULL, no cleanup is done for this TLS slot.
-    // Returns false on error.
-    bool Initialize(TLSDestructorFunc destructor);
+    void Initialize(TLSDestructorFunc destructor);
 
     // Free a previously allocated TLS 'slot'.
     // If a destructor was set for this slot, removes
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index e86c758..a89768e 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -194,12 +194,11 @@
   EXPECT_EQ("ThreadName", a.thread_name());
 }
 
-// Make sure Init() is called after Start() and before
-// WaitUntilThreadInitialized() returns.
+// Make sure we can't use a thread between Start() and Init().
 TEST_F(ThreadTest, SleepInsideInit) {
   SleepInsideInitThread t;
   EXPECT_FALSE(t.InitCalled());
-  t.StartAndWaitForTesting();
+  t.Start();
   EXPECT_TRUE(t.InitCalled());
 }
 
diff --git a/base/time/time.cc b/base/time/time.cc
index bf6c998..9834188 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -97,20 +97,21 @@
   return delta_;
 }
 
-int64 TimeDelta::SaturatedAdd(int64 value) const {
-  CheckedNumeric<int64> rv(delta_);
+namespace time_internal {
+
+int64 SaturatedAdd(TimeDelta delta, int64 value) {
+  CheckedNumeric<int64> rv(delta.delta_);
   rv += value;
   return FromCheckedNumeric(rv);
 }
 
-int64 TimeDelta::SaturatedSub(int64 value) const {
-  CheckedNumeric<int64> rv(delta_);
+int64 SaturatedSub(TimeDelta delta, int64 value) {
+  CheckedNumeric<int64> rv(delta.delta_);
   rv -= value;
   return FromCheckedNumeric(rv);
 }
 
-// static
-int64 TimeDelta::FromCheckedNumeric(const CheckedNumeric<int64> value) {
+int64 FromCheckedNumeric(const CheckedNumeric<int64> value) {
   if (value.IsValid())
     return value.ValueUnsafe();
 
@@ -124,6 +125,8 @@
   return value.ValueOrDefault(limit);
 }
 
+}  // namespace time_internal
+
 std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) {
   return os << time_delta.InSecondsF() << "s";
 }
@@ -305,15 +308,12 @@
                                        TimeDelta tick_interval) const {
   // |interval_offset| is the offset from |this| to the next multiple of
   // |tick_interval| after |tick_phase|, possibly negative if in the past.
-  TimeDelta interval_offset = TimeDelta::FromInternalValue(
-      (tick_phase - *this).ToInternalValue() % tick_interval.ToInternalValue());
+  TimeDelta interval_offset = (tick_phase - *this) % tick_interval;
   // If |this| is exactly on the interval (i.e. offset==0), don't adjust.
   // Otherwise, if |tick_phase| was in the past, adjust forward to the next
   // tick after |this|.
-  if (interval_offset.ToInternalValue() != 0 && tick_phase < *this) {
+  if (!interval_offset.is_zero() && tick_phase < *this)
     interval_offset += tick_interval;
-  }
-
   return *this + interval_offset;
 }
 
diff --git a/base/time/time.h b/base/time/time.h
index 5c8b89c..0a26778 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -57,8 +57,23 @@
 
 namespace base {
 
-class Time;
-class TimeTicks;
+class TimeDelta;
+
+// The functions in the time_internal namespace are meant to be used only by the
+// time classes and functions.  Please use the math operators defined in the
+// time classes instead.
+namespace time_internal {
+
+// Add or subtract |value| from a TimeDelta. The int64 argument and return value
+// are in terms of a microsecond timebase.
+BASE_EXPORT int64 SaturatedAdd(TimeDelta delta, int64 value);
+BASE_EXPORT int64 SaturatedSub(TimeDelta delta, int64 value);
+
+// Clamp |value| on overflow and underflow conditions. The int64 argument and
+// return value are in terms of a microsecond timebase.
+BASE_EXPORT int64 FromCheckedNumeric(const CheckedNumeric<int64> value);
+
+}  // namespace time_internal
 
 // TimeDelta ------------------------------------------------------------------
 
@@ -110,6 +125,11 @@
     return TimeDelta((delta_ + mask) ^ mask);
   }
 
+  // Returns true if the time delta is zero.
+  bool is_zero() const {
+    return delta_ == 0;
+  }
+
   // Returns true if the time delta is the maximum time delta.
   bool is_max() const {
     return delta_ == std::numeric_limits<int64>::max();
@@ -141,19 +161,17 @@
 
   // Computations with other deltas.
   TimeDelta operator+(TimeDelta other) const {
-    return TimeDelta(SaturatedAdd(other.delta_));
+    return TimeDelta(time_internal::SaturatedAdd(*this, other.delta_));
   }
   TimeDelta operator-(TimeDelta other) const {
-    return TimeDelta(SaturatedSub(other.delta_));
+    return TimeDelta(time_internal::SaturatedSub(*this, other.delta_));
   }
 
   TimeDelta& operator+=(TimeDelta other) {
-    delta_ = SaturatedAdd(other.delta_);
-    return *this;
+    return *this = (*this + other);
   }
   TimeDelta& operator-=(TimeDelta other) {
-    delta_ = SaturatedSub(other.delta_);
-    return *this;
+    return *this = (*this - other);
   }
   TimeDelta operator-() const {
     return TimeDelta(-delta_);
@@ -164,36 +182,29 @@
   TimeDelta operator*(T a) const {
     CheckedNumeric<int64> rv(delta_);
     rv *= a;
-    return TimeDelta(FromCheckedNumeric(rv));
+    return TimeDelta(time_internal::FromCheckedNumeric(rv));
   }
   template<typename T>
   TimeDelta operator/(T a) const {
     CheckedNumeric<int64> rv(delta_);
     rv /= a;
-    return TimeDelta(FromCheckedNumeric(rv));
+    return TimeDelta(time_internal::FromCheckedNumeric(rv));
   }
   template<typename T>
   TimeDelta& operator*=(T a) {
-    CheckedNumeric<int64> rv(delta_);
-    rv *= a;
-    delta_ = FromCheckedNumeric(rv);
-    return *this;
+    return *this = (*this * a);
   }
   template<typename T>
   TimeDelta& operator/=(T a) {
-    CheckedNumeric<int64> rv(delta_);
-    rv /= a;
-    delta_ = FromCheckedNumeric(rv);
-    return *this;
+    return *this = (*this / a);
   }
 
   int64 operator/(TimeDelta a) const {
     return delta_ / a.delta_;
   }
-
-  // Defined below because it depends on the definition of the other classes.
-  Time operator+(Time t) const;
-  TimeTicks operator+(TimeTicks t) const;
+  TimeDelta operator%(TimeDelta a) const {
+    return TimeDelta(delta_ % a.delta_);
+  }
 
   // Comparison operators.
   bool operator==(TimeDelta other) const {
@@ -216,8 +227,8 @@
   }
 
  private:
-  friend class Time;
-  friend class TimeTicks;
+  friend int64 time_internal::SaturatedAdd(TimeDelta delta, int64 value);
+  friend int64 time_internal::SaturatedSub(TimeDelta delta, int64 value);
 
   // Constructs a delta given the duration in microseconds. This is private
   // to avoid confusion by callers with an integer constructor. Use
@@ -225,13 +236,6 @@
   explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
   }
 
-  // Add or subtract |value| from this delta.
-  int64 SaturatedAdd(int64 value) const;
-  int64 SaturatedSub(int64 value) const;
-
-  // Clamp |value| on overflow and underflow conditions.
-  static int64 FromCheckedNumeric(const CheckedNumeric<int64> value);
-
   // Delta in microseconds.
   int64 delta_;
 };
@@ -244,10 +248,19 @@
 // For logging use only.
 BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta);
 
-// Time -----------------------------------------------------------------------
+// Do not reference the time_internal::TimeBase template class directly.  Please
+// use one of the time subclasses instead, and only reference the public
+// TimeBase members via those classes.
+namespace time_internal {
 
-// Represents a wall clock time in UTC.
-class BASE_EXPORT Time {
+// TimeBase--------------------------------------------------------------------
+
+// Provides value storage and comparison/math operations common to all time
+// classes. Each subclass provides for strong type-checking to ensure
+// semantically meaningful comparison/math of time values from the same clock
+// source or timeline.
+template<class TimeClass>
+class TimeBase {
  public:
   static const int64 kHoursPerDay = 24;
   static const int64 kMillisecondsPerSecond = 1000;
@@ -264,6 +277,102 @@
   static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
                                              kMicrosecondsPerSecond;
 
+  // Returns true if this object has not been initialized.
+  //
+  // Warning: Be careful when writing code that performs math on time values,
+  // since it's possible to produce a valid "zero" result that should not be
+  // interpreted as a "null" value.
+  bool is_null() const {
+    return us_ == 0;
+  }
+
+  // Returns true if this object represents the maximum time.
+  bool is_max() const {
+    return us_ == std::numeric_limits<int64>::max();
+  }
+
+  // For serializing only. Use FromInternalValue() to reconstitute. Please don't
+  // use this and do arithmetic on it, as it is more error prone than using the
+  // provided operators.
+  int64 ToInternalValue() const {
+    return us_;
+  }
+
+  TimeClass& operator=(TimeClass other) {
+    us_ = other.us_;
+    return *(static_cast<TimeClass*>(this));
+  }
+
+  // Compute the difference between two times.
+  TimeDelta operator-(TimeClass other) const {
+    return TimeDelta::FromMicroseconds(us_ - other.us_);
+  }
+
+  // Return a new time modified by some delta.
+  TimeClass operator+(TimeDelta delta) const {
+    return TimeClass(time_internal::SaturatedAdd(delta, us_));
+  }
+  TimeClass operator-(TimeDelta delta) const {
+    return TimeClass(-time_internal::SaturatedSub(delta, us_));
+  }
+
+  // Modify by some time delta.
+  TimeClass& operator+=(TimeDelta delta) {
+    return static_cast<TimeClass&>(*this = (*this + delta));
+  }
+  TimeClass& operator-=(TimeDelta delta) {
+    return static_cast<TimeClass&>(*this = (*this - delta));
+  }
+
+  // Comparison operators
+  bool operator==(TimeClass other) const {
+    return us_ == other.us_;
+  }
+  bool operator!=(TimeClass other) const {
+    return us_ != other.us_;
+  }
+  bool operator<(TimeClass other) const {
+    return us_ < other.us_;
+  }
+  bool operator<=(TimeClass other) const {
+    return us_ <= other.us_;
+  }
+  bool operator>(TimeClass other) const {
+    return us_ > other.us_;
+  }
+  bool operator>=(TimeClass other) const {
+    return us_ >= other.us_;
+  }
+
+  // Converts an integer value representing TimeClass to a class. This is used
+  // when deserializing a |TimeClass| structure, using a value known to be
+  // compatible. It is not provided as a constructor because the integer type
+  // may be unclear from the perspective of a caller.
+  static TimeClass FromInternalValue(int64 us) {
+    return TimeClass(us);
+  }
+
+ protected:
+  explicit TimeBase(int64 us) : us_(us) {
+  }
+
+  // Time value in a microsecond timebase.
+  int64 us_;
+};
+
+}  // namespace time_internal
+
+template<class TimeClass>
+inline TimeClass operator+(TimeDelta delta, TimeClass t) {
+  return t + delta;
+}
+
+// Time -----------------------------------------------------------------------
+
+// Represents a wall clock time in UTC. Values are not guaranteed to be
+// monotonically non-decreasing and are subject to large amounts of skew.
+class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
+ public:
   // The representation of Jan 1, 1970 UTC in microseconds since the
   // platform-dependent epoch.
   static const int64 kTimeTToMicrosecondsOffset;
@@ -303,17 +412,7 @@
   };
 
   // Contains the NULL time. Use Time::Now() to get the current time.
-  Time() : us_(0) {
-  }
-
-  // Returns true if the time object has not been initialized.
-  bool is_null() const {
-    return us_ == 0;
-  }
-
-  // Returns true if the time object is the maximum time.
-  bool is_max() const {
-    return us_ == std::numeric_limits<int64>::max();
+  Time() : TimeBase(0) {
   }
 
   // Returns the time for epoch in Unix-like system (Jan 1, 1970).
@@ -412,14 +511,6 @@
     return FromExploded(true, exploded);
   }
 
-  // Converts an integer value representing Time to a class. This is used
-  // when deserializing a |Time| structure, using a value known to be
-  // compatible. It is not provided as a constructor because the integer type
-  // may be unclear from the perspective of a caller.
-  static Time FromInternalValue(int64 us) {
-    return Time(us);
-  }
-
   // Converts a string representation of time to a Time object.
   // An example of a time string which is converted is as below:-
   // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
@@ -435,13 +526,6 @@
     return FromStringInternal(time_string, false, parsed_time);
   }
 
-  // For serializing, use FromInternalValue to reconstitute. Please don't use
-  // this and do arithmetic on it, as it is more error prone than using the
-  // provided operators.
-  int64 ToInternalValue() const {
-    return us_;
-  }
-
   // Fills the given exploded structure with either the local time or UTC from
   // this time structure (containing UTC).
   void UTCExplode(Exploded* exploded) const {
@@ -455,58 +539,10 @@
   // midnight on that day.
   Time LocalMidnight() const;
 
-  Time& operator=(Time other) {
-    us_ = other.us_;
-    return *this;
-  }
-
-  // Compute the difference between two times.
-  TimeDelta operator-(Time other) const {
-    return TimeDelta(us_ - other.us_);
-  }
-
-  // Modify by some time delta.
-  Time& operator+=(TimeDelta delta) {
-    us_ = delta.SaturatedAdd(us_);
-    return *this;
-  }
-  Time& operator-=(TimeDelta delta) {
-    us_ = -delta.SaturatedSub(us_);
-    return *this;
-  }
-
-  // Return a new time modified by some delta.
-  Time operator+(TimeDelta delta) const {
-    return Time(delta.SaturatedAdd(us_));
-  }
-  Time operator-(TimeDelta delta) const {
-    return Time(-delta.SaturatedSub(us_));
-  }
-
-  // Comparison operators
-  bool operator==(Time other) const {
-    return us_ == other.us_;
-  }
-  bool operator!=(Time other) const {
-    return us_ != other.us_;
-  }
-  bool operator<(Time other) const {
-    return us_ < other.us_;
-  }
-  bool operator<=(Time other) const {
-    return us_ <= other.us_;
-  }
-  bool operator>(Time other) const {
-    return us_ > other.us_;
-  }
-  bool operator>=(Time other) const {
-    return us_ >= other.us_;
-  }
-
  private:
-  friend class TimeDelta;
+  friend class time_internal::TimeBase<Time>;
 
-  explicit Time(int64 us) : us_(us) {
+  explicit Time(int64 us) : TimeBase(us) {
   }
 
   // Explodes the given time to either local time |is_local = true| or UTC
@@ -527,9 +563,6 @@
   static bool FromStringInternal(const char* time_string,
                                  bool is_local,
                                  Time* parsed_time);
-
-  // Time in microseconds in UTC.
-  int64 us_;
 };
 
 // Inline the TimeDelta factory methods, for fast TimeDelta construction.
@@ -598,16 +631,13 @@
   return TimeDelta(us);
 }
 
-inline Time TimeDelta::operator+(Time t) const {
-  return Time(SaturatedAdd(t.us_));
-}
-
 // For logging use only.
 BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time);
 
 // TimeTicks ------------------------------------------------------------------
 
-class BASE_EXPORT TimeTicks {
+// Represents monotonically non-decreasing clock time.
+class BASE_EXPORT TimeTicks : public time_internal::TimeBase<TimeTicks> {
  public:
   // We define this even without OS_CHROMEOS for seccomp sandbox testing.
 #if defined(OS_LINUX)
@@ -617,7 +647,7 @@
   static const clockid_t kClockSystemTrace = 11;
 #endif
 
-  TimeTicks() : ticks_(0) {
+  TimeTicks() : TimeBase(0) {
   }
 
   // Platform-dependent tick count representing "right now." When
@@ -676,24 +706,6 @@
   static TimeTicks FromQPCValue(LONGLONG qpc_value);
 #endif
 
-  // Returns true if this object has not been initialized.
-  bool is_null() const {
-    return ticks_ == 0;
-  }
-
-  // Returns true if the time delta is the maximum delta.
-  bool is_max() const {
-    return ticks_ == std::numeric_limits<int64>::max();
-  }
-
-  // Converts an integer value representing TimeTicks to a class. This is used
-  // when deserializing a |TimeTicks| structure, using a value known to be
-  // compatible. It is not provided as a constructor because the integer type
-  // may be unclear from the perspective of a caller.
-  static TimeTicks FromInternalValue(int64 ticks) {
-    return TimeTicks(ticks);
-  }
-
   // Get the TimeTick value at the time of the UnixEpoch. This is useful when
   // you need to relate the value of TimeTicks to a real time and date.
   // Note: Upon first invocation, this function takes a snapshot of the realtime
@@ -702,86 +714,26 @@
   // application runs.
   static TimeTicks UnixEpoch();
 
-  // Returns the internal numeric value of the TimeTicks object.
-  // For serializing, use FromInternalValue to reconstitute.
-  int64 ToInternalValue() const {
-    return ticks_;
-  }
-
   // Returns |this| snapped to the next tick, given a |tick_phase| and
   // repeating |tick_interval| in both directions. |this| may be before,
   // after, or equal to the |tick_phase|.
   TimeTicks SnappedToNextTick(TimeTicks tick_phase,
                               TimeDelta tick_interval) const;
 
-  TimeTicks& operator=(TimeTicks other) {
-    ticks_ = other.ticks_;
-    return *this;
-  }
-
-  // Compute the difference between two times.
-  TimeDelta operator-(TimeTicks other) const {
-    return TimeDelta(ticks_ - other.ticks_);
-  }
-
-  // Modify by some time delta.
-  TimeTicks& operator+=(TimeDelta delta) {
-    ticks_ = delta.SaturatedAdd(ticks_);
-    return *this;
-  }
-  TimeTicks& operator-=(TimeDelta delta) {
-    ticks_ = -delta.SaturatedSub(ticks_);
-    return *this;
-  }
-
-  // Return a new TimeTicks modified by some delta.
-  TimeTicks operator+(TimeDelta delta) const {
-    return TimeTicks(delta.SaturatedAdd(ticks_));
-  }
-  TimeTicks operator-(TimeDelta delta) const {
-    return TimeTicks(-delta.SaturatedSub(ticks_));
-  }
-
-  // Comparison operators
-  bool operator==(TimeTicks other) const {
-    return ticks_ == other.ticks_;
-  }
-  bool operator!=(TimeTicks other) const {
-    return ticks_ != other.ticks_;
-  }
-  bool operator<(TimeTicks other) const {
-    return ticks_ < other.ticks_;
-  }
-  bool operator<=(TimeTicks other) const {
-    return ticks_ <= other.ticks_;
-  }
-  bool operator>(TimeTicks other) const {
-    return ticks_ > other.ticks_;
-  }
-  bool operator>=(TimeTicks other) const {
-    return ticks_ >= other.ticks_;
-  }
-
- protected:
-  friend class TimeDelta;
-
-  // Please use Now() to create a new object. This is for internal use
-  // and testing. Ticks is in microseconds.
-  explicit TimeTicks(int64 ticks) : ticks_(ticks) {
-  }
-
-  // Tick count in microseconds.
-  int64 ticks_;
-
 #if defined(OS_WIN)
+ protected:
   typedef DWORD (*TickFunctionType)(void);
   static TickFunctionType SetMockTickFunction(TickFunctionType ticker);
 #endif
-};
 
-inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
-  return TimeTicks(SaturatedAdd(t.ticks_));
-}
+ private:
+  friend class time_internal::TimeBase<TimeTicks>;
+
+  // Please use Now() to create a new object. This is for internal use
+  // and testing.
+  explicit TimeTicks(int64 us) : TimeBase(us) {
+  }
+};
 
 // For logging use only.
 BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks);
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index 6c12423..456782c 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -717,7 +717,7 @@
 
 TEST(TimeTicks, SnappedToNextTickBasic) {
   base::TimeTicks phase = base::TimeTicks::FromInternalValue(4000);
-  base::TimeDelta interval = base::TimeDelta::FromInternalValue(1000);
+  base::TimeDelta interval = base::TimeDelta::FromMicroseconds(1000);
   base::TimeTicks timestamp;
 
   // Timestamp in previous interval.
@@ -760,7 +760,7 @@
   // int(big_timestamp / interval) < 0, so this causes a crash if the number of
   // intervals elapsed is attempted to be stored in an int.
   base::TimeTicks phase = base::TimeTicks::FromInternalValue(0);
-  base::TimeDelta interval = base::TimeDelta::FromInternalValue(4000);
+  base::TimeDelta interval = base::TimeDelta::FromMicroseconds(4000);
   base::TimeTicks big_timestamp =
       base::TimeTicks::FromInternalValue(8635916564000);
 
diff --git a/base/trace_event/memory_allocator_dump.cc b/base/trace_event/memory_allocator_dump.cc
index 77c32ec..edec31b 100644
--- a/base/trace_event/memory_allocator_dump.cc
+++ b/base/trace_event/memory_allocator_dump.cc
@@ -109,7 +109,7 @@
   value->BeginDictionary("attrs");
 
   for (DictionaryValue::Iterator it(attributes_); !it.IsAtEnd(); it.Advance())
-    value->SetValue(it.key().c_str(), it.value().DeepCopy());
+    value->SetValue(it.key().c_str(), it.value().CreateDeepCopy());
 
   value->EndDictionary();  // "attrs": { ... }
   value->EndDictionary();  // "allocator_name/heap_subheap": { ... }
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h
index 4fb0335..4d3763a 100644
--- a/base/trace_event/memory_dump_request_args.h
+++ b/base/trace_event/memory_dump_request_args.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
+#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
 
 // This file defines the types and structs used to issue memory dump requests.
 // These are also used in the IPCs for coordinating inter-process memory dumps.
@@ -38,4 +38,4 @@
 }  // namespace trace_event
 }  // namespace base
 
-#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index 86f959f..2c30b33 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -400,6 +400,13 @@
     INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
         TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
         timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2( \
+        category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+        arg2_name, arg2_val) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+        TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
+        timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
+        arg2_val)
 
 // Records a single END event for "name" immediately. If the category
 // is not enabled, then this does nothing.
@@ -449,6 +456,13 @@
     INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
         TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
         timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2( \
+        category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+        arg2_name, arg2_val) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+        TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
+        timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
+        arg2_val)
 
 // Records the value of a counter called "name" immediately. Value
 // must be representable as a 32 bit integer.
@@ -702,27 +716,43 @@
 // NESTABLE_ASYNC event of that id. Corresponding warning messages for
 // unmatched events will be shown in the analysis view.
 
-// Records a single NESTABLE_ASYNC_BEGIN event called "name" immediately, with 2
-// associated arguments. If the category is not enabled, then this does nothing.
+// Records a single NESTABLE_ASYNC_BEGIN event called "name" immediately, with
+// 0, 1 or 2 associated arguments. If the category is not enabled, then this
+// does nothing.
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+        category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+        arg1_val) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
         arg1_val, arg2_name, arg2_val) \
     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
         category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
         arg2_name, arg2_val)
+// Records a single NESTABLE_ASYNC_END event called "name" immediately, with 0,
+// 1, or 2 associated arguments. If the category is not enabled, then this does
+// nothing.
+#define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+        category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
+        arg1_val) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
+        arg1_val, arg2_name, arg2_val) \
+    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+        arg2_name, arg2_val)
+
 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2(category_group, name, \
         id, arg1_name, arg1_val, arg2_name, arg2_val) \
     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
         category_group, name, id, \
         TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, \
         arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Records a single NESTABLE_ASYNC_END event called "name" immediately, with 2
-// associated arguments. If the category is not enabled, then this does nothing.
-#define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
-        arg1_val, arg2_name, arg2_val) \
-    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
-        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
-        arg2_name, arg2_val)
 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2(category_group, name, \
         id, arg1_name, arg1_val, arg2_name, arg2_val) \
     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
@@ -1445,8 +1475,8 @@
     const char* name,
     unsigned long long id,
     unsigned char flags) {
-  int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
-  base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+  const int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+  const base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
   return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
                                                name, id, thread_id, now, flags);
 }
diff --git a/base/trace_event/trace_event_argument.cc b/base/trace_event/trace_event_argument.cc
index 91ed9e8..88b1879 100644
--- a/base/trace_event/trace_event_argument.cc
+++ b/base/trace_event/trace_event_argument.cc
@@ -34,19 +34,19 @@
   GetCurrentDictionary()->SetString(name, value);
 }
 
-void TracedValue::SetValue(const char* name, Value* value) {
-  GetCurrentDictionary()->Set(name, value);
+void TracedValue::SetValue(const char* name, scoped_ptr<Value> value) {
+  GetCurrentDictionary()->Set(name, value.Pass());
 }
 
 void TracedValue::BeginDictionary(const char* name) {
   DictionaryValue* dictionary = new DictionaryValue();
-  GetCurrentDictionary()->Set(name, dictionary);
+  GetCurrentDictionary()->Set(name, make_scoped_ptr(dictionary));
   stack_.push_back(dictionary);
 }
 
 void TracedValue::BeginArray(const char* name) {
   ListValue* array = new ListValue();
-  GetCurrentDictionary()->Set(name, array);
+  GetCurrentDictionary()->Set(name, make_scoped_ptr(array));
   stack_.push_back(array);
 }
 
diff --git a/base/trace_event/trace_event_argument.h b/base/trace_event/trace_event_argument.h
index 78d37d4..d86cfd1 100644
--- a/base/trace_event/trace_event_argument.h
+++ b/base/trace_event/trace_event_argument.h
@@ -29,7 +29,7 @@
   void SetDouble(const char* name, double);
   void SetBoolean(const char* name, bool value);
   void SetString(const char* name, const std::string& value);
-  void SetValue(const char* name, Value* value);
+  void SetValue(const char* name, scoped_ptr<Value> value);
   void BeginDictionary(const char* name);
   void BeginArray(const char* name);
 
@@ -49,7 +49,7 @@
   ListValue* GetCurrentArray();
 
   scoped_ptr<base::Value> root_;
-  std::vector<Value*> stack_;
+  std::vector<Value*> stack_;  // Weak references.
   DISALLOW_COPY_AND_ASSIGN(TracedValue);
 };
 
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc
index f7f9ecc..1cb3b8c 100644
--- a/base/trace_event/trace_event_etw_export_win.cc
+++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -106,12 +106,14 @@
 
 // static
 void TraceEventETWExport::EnableETWExport() {
-  GetInstance()->ETWExportEnabled_ = true;
+  if (GetInstance())
+    GetInstance()->ETWExportEnabled_ = true;
 }
 
 // static
 void TraceEventETWExport::DisableETWExport() {
-  GetInstance()->ETWExportEnabled_ = false;
+  if (GetInstance())
+    GetInstance()->ETWExportEnabled_ = false;
 }
 
 // static
@@ -126,7 +128,8 @@
     const unsigned long long* arg_values,
     const scoped_refptr<ConvertableToTraceFormat>* convertable_values) {
   // We bail early in case exporting is disabled or no consumer is listening.
-  if (!GetInstance()->ETWExportEnabled_ || !EventEnabledChromeEvent())
+  if (!GetInstance() || !GetInstance()->ETWExportEnabled_ ||
+      !EventEnabledChromeEvent())
     return;
 
   std::string phase_string;
@@ -224,7 +227,8 @@
                                          const char* arg_value_2,
                                          const char* arg_name_3,
                                          const char* arg_value_3) {
-  if (!GetInstance()->ETWExportEnabled_ || !EventEnabledChromeEvent())
+  if (!GetInstance() || !GetInstance()->ETWExportEnabled_ ||
+      !EventEnabledChromeEvent())
     return;
 
   EventWriteChromeEvent(name, phase, arg_name_1, arg_value_1, arg_name_2,
diff --git a/base/trace_event/trace_event_etw_export_win.h b/base/trace_event/trace_event_etw_export_win.h
index 0a551c3..eefe820 100644
--- a/base/trace_event/trace_event_etw_export_win.h
+++ b/base/trace_event/trace_event_etw_export_win.h
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 // This file contains the Windows-specific exporting to ETW.
-#ifndef BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
-#define BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#ifndef BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
+#define BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
 
 #include "base/base_export.h"
 #include "base/trace_event/trace_event_impl.h"
@@ -29,7 +29,9 @@
   static void EnableETWExport();
   static void DisableETWExport();
 
-  static bool isETWExportEnabled() { return GetInstance()->ETWExportEnabled_; }
+  static bool isETWExportEnabled() {
+    return (GetInstance() && GetInstance()->ETWExportEnabled_);
+  }
 
   // Exports an event to ETW. This is mainly used in
   // TraceLog::AddTraceEventWithThreadIdAndTimestamp to export internal events.
@@ -70,4 +72,4 @@
 }  // namespace trace_event
 }  // namespace base
 
-#endif  // BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#endif  // BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
diff --git a/base/trace_event/trace_event_memory.cc b/base/trace_event/trace_event_memory.cc
index ab8ba0d..8959589 100644
--- a/base/trace_event/trace_event_memory.cc
+++ b/base/trace_event/trace_event_memory.cc
@@ -71,13 +71,12 @@
   delete stack;
 }
 
-// Initializes the thread-local TraceMemoryStack pointer. Returns true on
-// success or if it is already initialized.
-bool InitThreadLocalStorage() {
+// Initializes the thread-local TraceMemoryStack pointer.
+void InitThreadLocalStorage() {
   if (tls_trace_memory_stack.initialized())
-    return true;
-  // Initialize the thread-local storage key, returning true on success.
-  return tls_trace_memory_stack.Initialize(&DeleteStackOnThreadCleanup);
+    return;
+  // Initialize the thread-local storage key.
+  tls_trace_memory_stack.Initialize(&DeleteStackOnThreadCleanup);
 }
 
 // Clean up thread-local-storage in the main thread.
@@ -195,8 +194,7 @@
   if (dump_timer_.IsRunning())
     return;
   DVLOG(1) << "Starting trace memory";
-  if (!InitThreadLocalStorage())
-    return;
+  InitThreadLocalStorage();
   ScopedTraceMemory::set_enabled(true);
   // Call ::HeapProfilerWithPseudoStackStart().
   heap_profiler_start_function_(&GetPseudoStack);
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 17953e7..d032243 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -1527,7 +1527,7 @@
 
     // See if this thread name is one of the threads we just created
     for (int j = 0; j < kNumThreads; j++) {
-      if(static_cast<int>(thread_ids[j]) != tmp_int)
+      if (static_cast<int>(thread_ids[j]) != tmp_int)
         continue;
 
       std::string expected_name = StringPrintf("Thread %d", j);
@@ -2214,7 +2214,7 @@
   }
   void TearDown() override {
     TraceLog::GetInstance()->SetDisabled();
-    ASSERT_TRUE(!!s_instance);
+    ASSERT_TRUE(s_instance);
     s_instance = NULL;
     TraceEventTestFixture::TearDown();
   }
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc
index 9029f4f..9db05c0 100644
--- a/base/tracked_objects.cc
+++ b/base/tracked_objects.cc
@@ -168,32 +168,6 @@
   }
 }
 
-int DeathData::count() const { return count_; }
-
-int32 DeathData::run_duration_sum() const { return run_duration_sum_; }
-
-int32 DeathData::run_duration_max() const { return run_duration_max_; }
-
-int32 DeathData::run_duration_sample() const {
-  return run_duration_sample_;
-}
-
-int32 DeathData::queue_duration_sum() const {
-  return queue_duration_sum_;
-}
-
-int32 DeathData::queue_duration_max() const {
-  return queue_duration_max_;
-}
-
-int32 DeathData::queue_duration_sample() const {
-  return queue_duration_sample_;
-}
-
-const DeathDataPhaseSnapshot* DeathData::last_phase_snapshot() const {
-  return last_phase_snapshot_;
-}
-
 void DeathData::OnProfilingPhaseCompleted(int profiling_phase) {
   // Snapshotting and storing current state.
   last_phase_snapshot_ = new DeathDataPhaseSnapshot(
@@ -388,8 +362,7 @@
 
 // static
 void ThreadData::InitializeThreadContext(const std::string& suggested_name) {
-  if (!Initialize())  // Always initialize if needed.
-    return;
+  Initialize();
   ThreadData* current_thread_data =
       reinterpret_cast<ThreadData*>(tls_index_.Get());
   if (current_thread_data)
@@ -718,9 +691,9 @@
     ThreadData::SetAlternateTimeSource(alternate_time_source);
 }
 
-bool ThreadData::Initialize() {
+void ThreadData::Initialize() {
   if (status_ >= DEACTIVATED)
-    return true;  // Someone else did the initialization.
+    return;  // Someone else did the initialization.
   // Due to racy lazy initialization in tests, we'll need to recheck status_
   // after we acquire the lock.
 
@@ -729,7 +702,7 @@
   // initialization.
   base::AutoLock lock(*list_lock_.Pointer());
   if (status_ >= DEACTIVATED)
-    return true;  // Someone raced in here and beat us.
+    return;  // Someone raced in here and beat us.
 
   // Put an alternate timer in place if the environment calls for it, such as
   // for tracking TCMalloc allocations.  This insertion is idempotent, so we
@@ -743,8 +716,7 @@
   if (!tls_index_.initialized()) {  // Testing may have initialized this.
     DCHECK_EQ(status_, UNINITIALIZED);
     tls_index_.Initialize(&ThreadData::OnThreadTermination);
-    if (!tls_index_.initialized())
-      return false;
+    DCHECK(tls_index_.initialized());
   } else {
     // TLS was initialzed for us earlier.
     DCHECK_EQ(status_, DORMANT_DURING_TESTS);
@@ -759,21 +731,18 @@
   // we get the lock earlier in this method.
   status_ = kInitialStartupState;
   DCHECK(status_ != UNINITIALIZED);
-  return true;
 }
 
 // static
-bool ThreadData::InitializeAndSetTrackingStatus(Status status) {
+void ThreadData::InitializeAndSetTrackingStatus(Status status) {
   DCHECK_GE(status, DEACTIVATED);
   DCHECK_LE(status, PROFILING_ACTIVE);
 
-  if (!Initialize())  // No-op if already initialized.
-    return false;  // Not compiled in.
+  Initialize();  // No-op if already initialized.
 
   if (status > DEACTIVATED)
     status = PROFILING_ACTIVE;
   status_ = status;
-  return true;
 }
 
 // static
@@ -827,8 +796,8 @@
   // This is only called from test code, where we need to cleanup so that
   // additional tests can be run.
   // We must be single threaded... but be careful anyway.
-  if (!InitializeAndSetTrackingStatus(DEACTIVATED))
-    return;
+  InitializeAndSetTrackingStatus(DEACTIVATED);
+
   ThreadData* thread_data_list;
   {
     base::AutoLock lock(*list_lock_.Pointer());
diff --git a/base/tracked_objects.h b/base/tracked_objects.h
index cd69fb7..8f83794 100644
--- a/base/tracked_objects.h
+++ b/base/tracked_objects.h
@@ -330,14 +330,16 @@
 
   // Metrics and past snapshots accessors, used only for serialization and in
   // tests.
-  int count() const;
-  int32 run_duration_sum() const;
-  int32 run_duration_max() const;
-  int32 run_duration_sample() const;
-  int32 queue_duration_sum() const;
-  int32 queue_duration_max() const;
-  int32 queue_duration_sample() const;
-  const DeathDataPhaseSnapshot* last_phase_snapshot() const;
+  int count() const { return count_; }
+  int32 run_duration_sum() const { return run_duration_sum_; }
+  int32 run_duration_max() const { return run_duration_max_; }
+  int32 run_duration_sample() const { return run_duration_sample_; }
+  int32 queue_duration_sum() const { return queue_duration_sum_; }
+  int32 queue_duration_max() const { return queue_duration_max_; }
+  int32 queue_duration_sample() const { return queue_duration_sample_; }
+  const DeathDataPhaseSnapshot* last_phase_snapshot() const {
+    return last_phase_snapshot_;
+  }
 
   // Called when the current profiling phase, identified by |profiling_phase|,
   // ends.
@@ -497,14 +499,13 @@
   const std::string& thread_name() const { return thread_name_; }
 
   // Initializes all statics if needed (this initialization call should be made
-  // while we are single threaded).  Returns false if unable to initialize.
-  static bool Initialize();
+  // while we are single threaded).
+  static void Initialize();
 
   // Sets internal status_.
   // If |status| is false, then status_ is set to DEACTIVATED.
   // If |status| is true, then status_ is set to PROFILING_ACTIVE.
-  // If it fails to initialize the TLS slot, this function will return false.
-  static bool InitializeAndSetTrackingStatus(Status status);
+  static void InitializeAndSetTrackingStatus(Status status);
 
   static Status status();
 
diff --git a/base/tracked_objects_unittest.cc b/base/tracked_objects_unittest.cc
index 3537e54..cdbf9ac 100644
--- a/base/tracked_objects_unittest.cc
+++ b/base/tracked_objects_unittest.cc
@@ -119,11 +119,7 @@
 unsigned int TrackedObjectsTest::test_time_;
 
 TEST_F(TrackedObjectsTest, TaskStopwatchNoStartStop) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   // Check that creating and destroying a stopwatch without starting it doesn't
   // crash.
@@ -132,11 +128,7 @@
 
 TEST_F(TrackedObjectsTest, MinimalStartupShutdown) {
   // Minimal test doesn't even create any tasks.
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   EXPECT_FALSE(ThreadData::first());  // No activity even on this thread.
   ThreadData* data = ThreadData::Get();
@@ -154,8 +146,7 @@
   Reset();
 
   // Do it again, just to be sure we reset state completely.
-  EXPECT_TRUE(
-      ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE));
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
   EXPECT_FALSE(ThreadData::first());  // No activity even on this thread.
   data = ThreadData::Get();
   EXPECT_TRUE(ThreadData::first());  // Now class was constructed.
@@ -170,11 +161,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TinyStartupShutdown) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   // Instigate tracking on a single tracked object, on our thread.
   const char kFunction[] = "TinyStartupShutdown";
@@ -250,11 +237,7 @@
 }
 
 TEST_F(TrackedObjectsTest, DeathDataTestRecordDeath) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   scoped_ptr<DeathData> data(new DeathData());
   ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
@@ -293,11 +276,7 @@
 }
 
 TEST_F(TrackedObjectsTest, DeathDataTest2Phases) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   scoped_ptr<DeathData> data(new DeathData());
   ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL));
@@ -362,11 +341,7 @@
 }
 
 TEST_F(TrackedObjectsTest, Delta) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   DeathDataSnapshot snapshot;
   snapshot.count = 10;
@@ -398,10 +373,7 @@
 
 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotWorkerThread) {
   // Start in the deactivated state.
-  if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED);
 
   const char kFunction[] = "DeactivatedBirthOnlyToSnapshotWorkerThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -423,10 +395,7 @@
 
 TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToSnapshotMainThread) {
   // Start in the deactivated state.
-  if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED);
 
   const char kFunction[] = "DeactivatedBirthOnlyToSnapshotMainThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -447,11 +416,7 @@
 }
 
 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotWorkerThread) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "BirthOnlyToSnapshotWorkerThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -464,11 +429,7 @@
 }
 
 TEST_F(TrackedObjectsTest, BirthOnlyToSnapshotMainThread) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "BirthOnlyToSnapshotMainThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -481,11 +442,7 @@
 }
 
 TEST_F(TrackedObjectsTest, LifeCycleToSnapshotMainThread) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "LifeCycleToSnapshotMainThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -514,11 +471,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TwoPhases) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TwoPhases";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -617,11 +570,7 @@
 }
 
 TEST_F(TrackedObjectsTest, ThreePhases) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "ThreePhases";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -762,11 +711,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TwoPhasesSecondEmpty) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TwoPhasesSecondEmpty";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -829,11 +774,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TwoPhasesFirstEmpty) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   ThreadData::OnProfilingPhaseCompleted(0);
 
@@ -894,11 +835,7 @@
 // our tallied births are matched by tallied deaths (except for when the
 // task is still running, or is queued).
 TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToSnapshotMainThread) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "LifeCycleMidDeactivatedToSnapshotMainThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -911,8 +848,7 @@
   pending_task.time_posted = kTimePosted;  // Overwrite implied Now().
 
   // Turn off tracking now that we have births.
-  EXPECT_TRUE(
-      ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED));
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED);
 
   const unsigned int kStartOfRun = 5;
   const unsigned int kEndOfRun = 7;
@@ -934,10 +870,7 @@
 // the birth nor the death will be recorded.
 TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToSnapshotMainThread) {
   // Start in the deactivated state.
-  if (!ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED);
 
   const char kFunction[] = "LifeCyclePreDeactivatedToSnapshotMainThread";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -974,11 +907,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TwoLives) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TwoLives";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -1018,11 +947,7 @@
 }
 
 TEST_F(TrackedObjectsTest, DifferentLives) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   // Use a well named thread.
   ThreadData::InitializeThreadContext(kMainThreadName);
@@ -1094,11 +1019,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TaskWithNestedExclusion) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TaskWithNestedExclusion";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -1132,11 +1053,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TaskWith2NestedExclusions) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TaskWith2NestedExclusions";
   Location location(kFunction, kFile, kLineNumber, NULL);
@@ -1176,11 +1093,7 @@
 }
 
 TEST_F(TrackedObjectsTest, TaskWithNestedExclusionWithNestedTask) {
-  if (!ThreadData::InitializeAndSetTrackingStatus(
-          ThreadData::PROFILING_ACTIVE)) {
-    // Don't run the test if task tracking is not compiled in.
-    return;
-  }
+  ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE);
 
   const char kFunction[] = "TaskWithNestedExclusionWithNestedTask";
   Location location(kFunction, kFile, kLineNumber, NULL);
diff --git a/base/tuple.h b/base/tuple.h
index 88c3075..4628aa9 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -25,8 +25,8 @@
 //   DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3));
 //   // foo->SomeMeth(1, 2, 3);
 
-#ifndef BASE_TUPLE_H__
-#define BASE_TUPLE_H__
+#ifndef BASE_TUPLE_H_
+#define BASE_TUPLE_H_
 
 #include "base/bind_helpers.h"
 
@@ -329,4 +329,4 @@
                        MakeIndexSequence<sizeof...(OutTs)>());
 }
 
-#endif  // BASE_TUPLE_H__
+#endif  // BASE_TUPLE_H_
diff --git a/base/values.cc b/base/values.cc
index 0e1e2b1..4093eba 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -85,8 +85,8 @@
 }
 
 // static
-Value* Value::CreateNullValue() {
-  return new Value(TYPE_NULL);
+scoped_ptr<Value> Value::CreateNullValue() {
+  return make_scoped_ptr(new Value(TYPE_NULL));
 }
 
 bool Value::GetAsBinary(const BinaryValue** out_value) const {
@@ -137,7 +137,11 @@
   // This method should only be getting called for null Values--all subclasses
   // need to provide their own implementation;.
   DCHECK(IsType(TYPE_NULL));
-  return CreateNullValue();
+  return CreateNullValue().release();
+}
+
+scoped_ptr<Value> Value::CreateDeepCopy() const {
+  return make_scoped_ptr(DeepCopy());
 }
 
 bool Value::Equals(const Value* other) const {
@@ -829,6 +833,10 @@
   return result;
 }
 
+scoped_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
+  return make_scoped_ptr(DeepCopy());
+}
+
 bool DictionaryValue::Equals(const Value* other) const {
   if (other->GetType() != GetType())
     return false;
@@ -883,6 +891,10 @@
   return true;
 }
 
+bool ListValue::Set(size_t index, scoped_ptr<Value> in_value) {
+  return Set(index, in_value.release());
+}
+
 bool ListValue::Get(size_t index, const Value** out_value) const {
   if (index >= list_.size())
     return false;
@@ -1032,6 +1044,10 @@
   return list_.erase(iter);
 }
 
+void ListValue::Append(scoped_ptr<Value> in_value) {
+  Append(in_value.release());
+}
+
 void ListValue::Append(Value* in_value) {
   DCHECK(in_value);
   list_.push_back(in_value);
@@ -1121,6 +1137,10 @@
   return result;
 }
 
+scoped_ptr<ListValue> ListValue::CreateDeepCopy() const {
+  return make_scoped_ptr(DeepCopy());
+}
+
 bool ListValue::Equals(const Value* other) const {
   if (other->GetType() != GetType())
     return false;
diff --git a/base/values.h b/base/values.h
index 1e1cae3..e32edec 100644
--- a/base/values.h
+++ b/base/values.h
@@ -64,7 +64,7 @@
 
   virtual ~Value();
 
-  static Value* CreateNullValue();
+  static scoped_ptr<Value> CreateNullValue();
 
   // Returns the type of the value stored by the current Value object.
   // Each type will be implemented by only one subclass of Value, so it's
@@ -99,6 +99,8 @@
   // Subclasses return their own type directly in their overrides;
   // this works because C++ supports covariant return types.
   virtual Value* DeepCopy() const;
+  // Preferred version of DeepCopy. TODO(estade): remove the above.
+  scoped_ptr<Value> CreateDeepCopy() const;
 
   // Compares if two Value objects have equal contents.
   virtual bool Equals(const Value* other) const;
@@ -368,6 +370,8 @@
 
   // Overridden from Value:
   DictionaryValue* DeepCopy() const override;
+  // Preferred version of DeepCopy. TODO(estade): remove the above.
+  scoped_ptr<DictionaryValue> CreateDeepCopy() const;
   bool Equals(const Value* other) const override;
 
  private:
@@ -400,6 +404,8 @@
   // Returns true if successful, or false if the index was negative or
   // the value is a null pointer.
   bool Set(size_t index, Value* in_value);
+  // Preferred version of the above. TODO(estade): remove the above.
+  bool Set(size_t index, scoped_ptr<Value> in_value);
 
   // Gets the Value at the given index.  Modifies |out_value| (and returns true)
   // only if the index falls within the current list range.
@@ -445,6 +451,8 @@
   iterator Erase(iterator iter, scoped_ptr<Value>* out_value);
 
   // Appends a Value to the end of the list.
+  void Append(scoped_ptr<Value> in_value);
+  // Deprecated version of the above. TODO(estade): remove.
   void Append(Value* in_value);
 
   // Convenience forms of Append.
@@ -486,6 +494,9 @@
   ListValue* DeepCopy() const override;
   bool Equals(const Value* other) const override;
 
+  // Preferred version of DeepCopy. TODO(estade): remove DeepCopy.
+  scoped_ptr<ListValue> CreateDeepCopy() const;
+
  private:
   ValueVector list_;
 
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index b66730b..6466a96 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -20,7 +20,7 @@
   ASSERT_EQ(std::string("http://google.com"), homepage);
 
   ASSERT_FALSE(settings.Get("global", NULL));
-  settings.Set("global", new FundamentalValue(true));
+  settings.SetBoolean("global", true);
   ASSERT_TRUE(settings.Get("global", NULL));
   settings.SetString("global.homepage", "http://scurvy.com");
   ASSERT_TRUE(settings.Get("global", NULL));
@@ -33,14 +33,14 @@
   ASSERT_FALSE(
     settings.GetList("global.toolbar.bookmarks", &toolbar_bookmarks));
 
-  toolbar_bookmarks = new ListValue;
-  settings.Set("global.toolbar.bookmarks", toolbar_bookmarks);
+  scoped_ptr<ListValue> new_toolbar_bookmarks(new ListValue);
+  settings.Set("global.toolbar.bookmarks", new_toolbar_bookmarks.Pass());
   ASSERT_TRUE(settings.GetList("global.toolbar.bookmarks", &toolbar_bookmarks));
 
-  DictionaryValue* new_bookmark = new DictionaryValue;
+  scoped_ptr<DictionaryValue> new_bookmark(new DictionaryValue);
   new_bookmark->SetString("name", "Froogle");
   new_bookmark->SetString("url", "http://froogle.com");
-  toolbar_bookmarks->Append(new_bookmark);
+  toolbar_bookmarks->Append(new_bookmark.Pass());
 
   ListValue* bookmark_list;
   ASSERT_TRUE(settings.GetList("global.toolbar.bookmarks", &bookmark_list));
@@ -57,10 +57,10 @@
 
 TEST(ValuesTest, List) {
   scoped_ptr<ListValue> mixed_list(new ListValue());
-  mixed_list->Set(0, new FundamentalValue(true));
-  mixed_list->Set(1, new FundamentalValue(42));
-  mixed_list->Set(2, new FundamentalValue(88.8));
-  mixed_list->Set(3, new StringValue("foo"));
+  mixed_list->Set(0, make_scoped_ptr(new FundamentalValue(true)));
+  mixed_list->Set(1, make_scoped_ptr(new FundamentalValue(42)));
+  mixed_list->Set(2, make_scoped_ptr(new FundamentalValue(88.8)));
+  mixed_list->Set(3, make_scoped_ptr(new StringValue("foo")));
   ASSERT_EQ(4u, mixed_list->GetSize());
 
   Value *value = NULL;
@@ -112,11 +112,12 @@
   ASSERT_EQ(0U, binary->GetSize());
 
   // Test the common case of a non-empty buffer
-  char* buffer = new char[15];
-  binary.reset(new BinaryValue(scoped_ptr<char[]>(buffer), 15));
+  scoped_ptr<char[]> buffer(new char[15]);
+  char* original_buffer = buffer.get();
+  binary.reset(new BinaryValue(buffer.Pass(), 15));
   ASSERT_TRUE(binary.get());
   ASSERT_TRUE(binary->GetBuffer());
-  ASSERT_EQ(buffer, binary->GetBuffer());
+  ASSERT_EQ(original_buffer, binary->GetBuffer());
   ASSERT_EQ(15U, binary->GetSize());
 
   char stack_buffer[42];
@@ -194,14 +195,14 @@
 
   {
     ListValue list;
-    list.Append(new DeletionTestValue(&deletion_flag));
+    list.Append(make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
   }
   EXPECT_TRUE(deletion_flag);
 
   {
     ListValue list;
-    list.Append(new DeletionTestValue(&deletion_flag));
+    list.Append(make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     list.Clear();
     EXPECT_TRUE(deletion_flag);
@@ -209,7 +210,7 @@
 
   {
     ListValue list;
-    list.Append(new DeletionTestValue(&deletion_flag));
+    list.Append(make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     EXPECT_TRUE(list.Set(0, Value::CreateNullValue()));
     EXPECT_TRUE(deletion_flag);
@@ -222,7 +223,7 @@
 
   {
     ListValue list;
-    list.Append(new DeletionTestValue(&deletion_flag));
+    list.Append(make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     EXPECT_EQ(1U, list.GetSize());
     EXPECT_FALSE(list.Remove(std::numeric_limits<size_t>::max(),
@@ -238,7 +239,7 @@
 
   {
     ListValue list;
-    list.Append(new DeletionTestValue(&deletion_flag));
+    list.Append(make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     EXPECT_TRUE(list.Remove(0, NULL));
     EXPECT_TRUE(deletion_flag);
@@ -247,11 +248,12 @@
 
   {
     ListValue list;
-    DeletionTestValue* value = new DeletionTestValue(&deletion_flag);
-    list.Append(value);
+    scoped_ptr<DeletionTestValue> value(new DeletionTestValue(&deletion_flag));
+    DeletionTestValue* original_value = value.get();
+    list.Append(value.Pass());
     EXPECT_FALSE(deletion_flag);
     size_t index = 0;
-    list.Remove(*value, &index);
+    list.Remove(*original_value, &index);
     EXPECT_EQ(0U, index);
     EXPECT_TRUE(deletion_flag);
     EXPECT_EQ(0U, list.GetSize());
@@ -264,14 +266,14 @@
 
   {
     DictionaryValue dict;
-    dict.Set(key, new DeletionTestValue(&deletion_flag));
+    dict.Set(key, make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
   }
   EXPECT_TRUE(deletion_flag);
 
   {
     DictionaryValue dict;
-    dict.Set(key, new DeletionTestValue(&deletion_flag));
+    dict.Set(key, make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     dict.Clear();
     EXPECT_TRUE(deletion_flag);
@@ -279,7 +281,7 @@
 
   {
     DictionaryValue dict;
-    dict.Set(key, new DeletionTestValue(&deletion_flag));
+    dict.Set(key, make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     dict.Set(key, Value::CreateNullValue());
     EXPECT_TRUE(deletion_flag);
@@ -293,7 +295,7 @@
 
   {
     DictionaryValue dict;
-    dict.Set(key, new DeletionTestValue(&deletion_flag));
+    dict.Set(key, make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     EXPECT_TRUE(dict.HasKey(key));
     EXPECT_FALSE(dict.Remove("absent key", &removed_item));
@@ -307,7 +309,7 @@
 
   {
     DictionaryValue dict;
-    dict.Set(key, new DeletionTestValue(&deletion_flag));
+    dict.Set(key, make_scoped_ptr(new DeletionTestValue(&deletion_flag)));
     EXPECT_FALSE(deletion_flag);
     EXPECT_TRUE(dict.HasKey(key));
     EXPECT_TRUE(dict.Remove(key, NULL));
@@ -318,9 +320,8 @@
 
 TEST(ValuesTest, DictionaryWithoutPathExpansion) {
   DictionaryValue dict;
-  dict.Set("this.is.expanded", make_scoped_ptr(Value::CreateNullValue()));
-  dict.SetWithoutPathExpansion("this.isnt.expanded",
-                               make_scoped_ptr(Value::CreateNullValue()));
+  dict.Set("this.is.expanded", Value::CreateNullValue());
+  dict.SetWithoutPathExpansion("this.isnt.expanded", Value::CreateNullValue());
 
   EXPECT_FALSE(dict.HasKey("this.is.expanded"));
   EXPECT_TRUE(dict.HasKey("this"));
@@ -390,36 +391,49 @@
 
 TEST(ValuesTest, DeepCopy) {
   DictionaryValue original_dict;
-  Value* original_null = Value::CreateNullValue();
-  original_dict.Set("null", make_scoped_ptr(original_null));
-  FundamentalValue* original_bool = new FundamentalValue(true);
-  original_dict.Set("bool", make_scoped_ptr(original_bool));
-  FundamentalValue* original_int = new FundamentalValue(42);
-  original_dict.Set("int", make_scoped_ptr(original_int));
-  FundamentalValue* original_double = new FundamentalValue(3.14);
-  original_dict.Set("double", make_scoped_ptr(original_double));
-  StringValue* original_string = new StringValue("hello");
-  original_dict.Set("string", make_scoped_ptr(original_string));
-  StringValue* original_string16 = new StringValue(ASCIIToUTF16("hello16"));
-  original_dict.Set("string16", make_scoped_ptr(original_string16));
+  scoped_ptr<Value> scoped_null = Value::CreateNullValue();
+  Value* original_null = scoped_null.get();
+  original_dict.Set("null", scoped_null.Pass());
+  scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
+  FundamentalValue* original_bool = scoped_bool.get();
+  original_dict.Set("bool", scoped_bool.Pass());
+  scoped_ptr<FundamentalValue> scoped_int(new FundamentalValue(42));
+  FundamentalValue* original_int = scoped_int.get();
+  original_dict.Set("int", scoped_int.Pass());
+  scoped_ptr<FundamentalValue> scoped_double(new FundamentalValue(3.14));
+  FundamentalValue* original_double = scoped_double.get();
+  original_dict.Set("double", scoped_double.Pass());
+  scoped_ptr<StringValue> scoped_string(new StringValue("hello"));
+  StringValue* original_string = scoped_string.get();
+  original_dict.Set("string", scoped_string.Pass());
+  scoped_ptr<StringValue> scoped_string16(
+      new StringValue(ASCIIToUTF16("hello16")));
+  StringValue* original_string16 = scoped_string16.get();
+  original_dict.Set("string16", scoped_string16.Pass());
 
   scoped_ptr<char[]> original_buffer(new char[42]);
   memset(original_buffer.get(), '!', 42);
-  BinaryValue* original_binary = new BinaryValue(original_buffer.Pass(), 42);
-  original_dict.Set("binary", original_binary);
+  scoped_ptr<BinaryValue> scoped_binary(
+      new BinaryValue(original_buffer.Pass(), 42));
+  BinaryValue* original_binary = scoped_binary.get();
+  original_dict.Set("binary", scoped_binary.Pass());
 
-  ListValue* original_list = new ListValue();
-  FundamentalValue* original_list_element_0 = new FundamentalValue(0);
-  original_list->Append(original_list_element_0);
-  FundamentalValue* original_list_element_1 = new FundamentalValue(1);
-  original_list->Append(original_list_element_1);
-  original_dict.Set("list", make_scoped_ptr(original_list));
+  scoped_ptr<ListValue> scoped_list(new ListValue());
+  Value* original_list = scoped_list.get();
+  scoped_ptr<FundamentalValue> scoped_list_element_0(new FundamentalValue(0));
+  Value* original_list_element_0 = scoped_list_element_0.get();
+  scoped_list->Append(scoped_list_element_0.Pass());
+  scoped_ptr<FundamentalValue> scoped_list_element_1(new FundamentalValue(1));
+  Value* original_list_element_1 = scoped_list_element_1.get();
+  scoped_list->Append(scoped_list_element_1.Pass());
+  original_dict.Set("list", scoped_list.Pass());
 
-  DictionaryValue* original_nested_dictionary = new DictionaryValue();
-  original_nested_dictionary->SetString("key", "value");
-  original_dict.Set("dictionary", make_scoped_ptr(original_nested_dictionary));
+  scoped_ptr<DictionaryValue> scoped_nested_dictionary(new DictionaryValue());
+  Value* original_nested_dictionary = scoped_nested_dictionary.get();
+  scoped_nested_dictionary->SetString("key", "value");
+  original_dict.Set("dictionary", scoped_nested_dictionary.Pass());
 
-  scoped_ptr<DictionaryValue> copy_dict(original_dict.DeepCopy());
+  scoped_ptr<DictionaryValue> copy_dict = original_dict.CreateDeepCopy();
   ASSERT_TRUE(copy_dict.get());
   ASSERT_NE(copy_dict.get(), &original_dict);
 
@@ -529,16 +543,13 @@
 }
 
 TEST(ValuesTest, Equals) {
-  Value* null1 = Value::CreateNullValue();
-  Value* null2 = Value::CreateNullValue();
-  EXPECT_NE(null1, null2);
-  EXPECT_TRUE(null1->Equals(null2));
+  scoped_ptr<Value> null1(Value::CreateNullValue());
+  scoped_ptr<Value> null2(Value::CreateNullValue());
+  EXPECT_NE(null1.get(), null2.get());
+  EXPECT_TRUE(null1->Equals(null2.get()));
 
-  Value* boolean = new FundamentalValue(false);
-  EXPECT_FALSE(null1->Equals(boolean));
-  delete null1;
-  delete null2;
-  delete boolean;
+  FundamentalValue boolean(false);
+  EXPECT_FALSE(null1->Equals(&boolean));
 
   DictionaryValue dv;
   dv.SetBoolean("a", false);
@@ -546,26 +557,27 @@
   dv.SetDouble("c", 2.5);
   dv.SetString("d1", "string");
   dv.SetString("d2", ASCIIToUTF16("http://google.com"));
-  dv.Set("e", make_scoped_ptr(Value::CreateNullValue()));
+  dv.Set("e", Value::CreateNullValue());
 
-  scoped_ptr<DictionaryValue> copy;
-  copy.reset(dv.DeepCopy());
+  scoped_ptr<DictionaryValue> copy = dv.CreateDeepCopy();
   EXPECT_TRUE(dv.Equals(copy.get()));
 
-  ListValue* list = new ListValue;
+  scoped_ptr<ListValue> list(new ListValue);
+  ListValue* original_list = list.get();
   list->Append(Value::CreateNullValue());
-  list->Append(new DictionaryValue);
-  dv.Set("f", make_scoped_ptr(list));
+  list->Append(make_scoped_ptr(new DictionaryValue));
+  scoped_ptr<Value> list_copy(list->CreateDeepCopy());
 
+  dv.Set("f", list.Pass());
   EXPECT_FALSE(dv.Equals(copy.get()));
-  copy->Set("f", list->DeepCopy());
+  copy->Set("f", list_copy.Pass());
   EXPECT_TRUE(dv.Equals(copy.get()));
 
-  list->Append(new FundamentalValue(true));
+  original_list->Append(make_scoped_ptr(new FundamentalValue(true)));
   EXPECT_FALSE(dv.Equals(copy.get()));
 
   // Check if Equals detects differences in only the keys.
-  copy.reset(dv.DeepCopy());
+  copy = dv.CreateDeepCopy();
   EXPECT_TRUE(dv.Equals(copy.get()));
   copy->Remove("a", NULL);
   copy->SetBoolean("aa", false);
@@ -597,57 +609,60 @@
 
 TEST(ValuesTest, DeepCopyCovariantReturnTypes) {
   DictionaryValue original_dict;
-  Value* original_null = Value::CreateNullValue();
-  original_dict.Set("null", original_null);
-  FundamentalValue* original_bool = new FundamentalValue(true);
-  original_dict.Set("bool", original_bool);
-  FundamentalValue* original_int = new FundamentalValue(42);
-  original_dict.Set("int", original_int);
-  FundamentalValue* original_double = new FundamentalValue(3.14);
-  original_dict.Set("double", original_double);
-  StringValue* original_string = new StringValue("hello");
-  original_dict.Set("string", original_string);
-  StringValue* original_string16 = new StringValue(ASCIIToUTF16("hello16"));
-  original_dict.Set("string16", original_string16);
+  scoped_ptr<Value> scoped_null(Value::CreateNullValue());
+  Value* original_null = scoped_null.get();
+  original_dict.Set("null", scoped_null.Pass());
+  scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
+  Value* original_bool = scoped_bool.get();
+  original_dict.Set("bool", scoped_bool.Pass());
+  scoped_ptr<FundamentalValue> scoped_int(new FundamentalValue(42));
+  Value* original_int = scoped_int.get();
+  original_dict.Set("int", scoped_int.Pass());
+  scoped_ptr<FundamentalValue> scoped_double(new FundamentalValue(3.14));
+  Value* original_double = scoped_double.get();
+  original_dict.Set("double", scoped_double.Pass());
+  scoped_ptr<StringValue> scoped_string(new StringValue("hello"));
+  Value* original_string = scoped_string.get();
+  original_dict.Set("string", scoped_string.Pass());
+  scoped_ptr<StringValue> scoped_string16(
+      new StringValue(ASCIIToUTF16("hello16")));
+  Value* original_string16 = scoped_string16.get();
+  original_dict.Set("string16", scoped_string16.Pass());
 
   scoped_ptr<char[]> original_buffer(new char[42]);
   memset(original_buffer.get(), '!', 42);
-  BinaryValue* original_binary = new BinaryValue(original_buffer.Pass(), 42);
-  original_dict.Set("binary", original_binary);
+  scoped_ptr<BinaryValue> scoped_binary(
+      new BinaryValue(original_buffer.Pass(), 42));
+  Value* original_binary = scoped_binary.get();
+  original_dict.Set("binary", scoped_binary.Pass());
 
-  ListValue* original_list = new ListValue();
-  FundamentalValue* original_list_element_0 = new FundamentalValue(0);
-  original_list->Append(original_list_element_0);
-  FundamentalValue* original_list_element_1 = new FundamentalValue(1);
-  original_list->Append(original_list_element_1);
-  original_dict.Set("list", original_list);
+  scoped_ptr<ListValue> scoped_list(new ListValue());
+  Value* original_list = scoped_list.get();
+  scoped_ptr<FundamentalValue> scoped_list_element_0(new FundamentalValue(0));
+  scoped_list->Append(scoped_list_element_0.Pass());
+  scoped_ptr<FundamentalValue> scoped_list_element_1(new FundamentalValue(1));
+  scoped_list->Append(scoped_list_element_1.Pass());
+  original_dict.Set("list", scoped_list.Pass());
 
-  Value* original_dict_value = &original_dict;
-  Value* original_bool_value = original_bool;
-  Value* original_int_value = original_int;
-  Value* original_double_value = original_double;
-  Value* original_string_value = original_string;
-  Value* original_string16_value = original_string16;
-  Value* original_binary_value = original_binary;
-  Value* original_list_value = original_list;
+  scoped_ptr<Value> copy_dict = original_dict.CreateDeepCopy();
+  scoped_ptr<Value> copy_null = original_null->CreateDeepCopy();
+  scoped_ptr<Value> copy_bool = original_bool->CreateDeepCopy();
+  scoped_ptr<Value> copy_int = original_int->CreateDeepCopy();
+  scoped_ptr<Value> copy_double = original_double->CreateDeepCopy();
+  scoped_ptr<Value> copy_string = original_string->CreateDeepCopy();
+  scoped_ptr<Value> copy_string16 = original_string16->CreateDeepCopy();
+  scoped_ptr<Value> copy_binary = original_binary->CreateDeepCopy();
+  scoped_ptr<Value> copy_list = original_list->CreateDeepCopy();
 
-  scoped_ptr<Value> copy_dict_value(original_dict_value->DeepCopy());
-  scoped_ptr<Value> copy_bool_value(original_bool_value->DeepCopy());
-  scoped_ptr<Value> copy_int_value(original_int_value->DeepCopy());
-  scoped_ptr<Value> copy_double_value(original_double_value->DeepCopy());
-  scoped_ptr<Value> copy_string_value(original_string_value->DeepCopy());
-  scoped_ptr<Value> copy_string16_value(original_string16_value->DeepCopy());
-  scoped_ptr<Value> copy_binary_value(original_binary_value->DeepCopy());
-  scoped_ptr<Value> copy_list_value(original_list_value->DeepCopy());
-
-  EXPECT_TRUE(original_dict_value->Equals(copy_dict_value.get()));
-  EXPECT_TRUE(original_bool_value->Equals(copy_bool_value.get()));
-  EXPECT_TRUE(original_int_value->Equals(copy_int_value.get()));
-  EXPECT_TRUE(original_double_value->Equals(copy_double_value.get()));
-  EXPECT_TRUE(original_string_value->Equals(copy_string_value.get()));
-  EXPECT_TRUE(original_string16_value->Equals(copy_string16_value.get()));
-  EXPECT_TRUE(original_binary_value->Equals(copy_binary_value.get()));
-  EXPECT_TRUE(original_list_value->Equals(copy_list_value.get()));
+  EXPECT_TRUE(original_dict.Equals(copy_dict.get()));
+  EXPECT_TRUE(original_null->Equals(copy_null.get()));
+  EXPECT_TRUE(original_bool->Equals(copy_bool.get()));
+  EXPECT_TRUE(original_int->Equals(copy_int.get()));
+  EXPECT_TRUE(original_double->Equals(copy_double.get()));
+  EXPECT_TRUE(original_string->Equals(copy_string.get()));
+  EXPECT_TRUE(original_string16->Equals(copy_string16.get()));
+  EXPECT_TRUE(original_binary->Equals(copy_binary.get()));
+  EXPECT_TRUE(original_list->Equals(copy_list.get()));
 }
 
 TEST(ValuesTest, RemoveEmptyChildren) {
@@ -662,7 +677,7 @@
 
   // Make sure we don't prune too much.
   root->SetBoolean("bool", true);
-  root->Set("empty_dict", new DictionaryValue);
+  root->Set("empty_dict", make_scoped_ptr(new DictionaryValue));
   root->SetString("empty_string", std::string());
   root.reset(root->DeepCopyWithoutEmptyChildren());
   EXPECT_EQ(2U, root->size());
@@ -674,55 +689,57 @@
   // Nested test cases.  These should all reduce back to the bool and string
   // set above.
   {
-    root->Set("a.b.c.d.e", new DictionaryValue);
+    root->Set("a.b.c.d.e", make_scoped_ptr(new DictionaryValue));
     root.reset(root->DeepCopyWithoutEmptyChildren());
     EXPECT_EQ(2U, root->size());
   }
   {
-    DictionaryValue* inner = new DictionaryValue;
-    root->Set("dict_with_emtpy_children", inner);
-    inner->Set("empty_dict", new DictionaryValue);
-    inner->Set("empty_list", new ListValue);
+    scoped_ptr<DictionaryValue> inner(new DictionaryValue);
+    inner->Set("empty_dict", make_scoped_ptr(new DictionaryValue));
+    inner->Set("empty_list", make_scoped_ptr(new ListValue));
+    root->Set("dict_with_empty_children", inner.Pass());
     root.reset(root->DeepCopyWithoutEmptyChildren());
     EXPECT_EQ(2U, root->size());
   }
   {
-    ListValue* inner = new ListValue;
-    root->Set("list_with_empty_children", inner);
-    inner->Append(new DictionaryValue);
-    inner->Append(new ListValue);
+    scoped_ptr<ListValue> inner(new ListValue);
+    inner->Append(make_scoped_ptr(new DictionaryValue));
+    inner->Append(make_scoped_ptr(new ListValue));
+    root->Set("list_with_empty_children", inner.Pass());
     root.reset(root->DeepCopyWithoutEmptyChildren());
     EXPECT_EQ(2U, root->size());
   }
 
   // Nested with siblings.
   {
-    ListValue* inner = new ListValue;
-    root->Set("list_with_empty_children", inner);
-    inner->Append(new DictionaryValue);
-    inner->Append(new ListValue);
-    DictionaryValue* inner2 = new DictionaryValue;
-    root->Set("dict_with_empty_children", inner2);
-    inner2->Set("empty_dict", new DictionaryValue);
-    inner2->Set("empty_list", new ListValue);
+    scoped_ptr<ListValue> inner(new ListValue());
+    inner->Append(make_scoped_ptr(new DictionaryValue));
+    inner->Append(make_scoped_ptr(new ListValue));
+    root->Set("list_with_empty_children", inner.Pass());
+    scoped_ptr<DictionaryValue> inner2(new DictionaryValue);
+    inner2->Set("empty_dict", make_scoped_ptr(new DictionaryValue));
+    inner2->Set("empty_list", make_scoped_ptr(new ListValue));
+    root->Set("dict_with_empty_children", inner2.Pass());
     root.reset(root->DeepCopyWithoutEmptyChildren());
     EXPECT_EQ(2U, root->size());
   }
 
   // Make sure nested values don't get pruned.
   {
-    ListValue* inner = new ListValue;
-    root->Set("list_with_empty_children", inner);
-    ListValue* inner2 = new ListValue;
-    inner->Append(new DictionaryValue);
-    inner->Append(inner2);
-    inner2->Append(new StringValue("hello"));
+    scoped_ptr<ListValue> inner(new ListValue);
+    scoped_ptr<ListValue> inner2(new ListValue);
+    inner2->Append(make_scoped_ptr(new StringValue("hello")));
+    inner->Append(make_scoped_ptr(new DictionaryValue));
+    inner->Append(inner2.Pass());
+    root->Set("list_with_empty_children", inner.Pass());
     root.reset(root->DeepCopyWithoutEmptyChildren());
     EXPECT_EQ(3U, root->size());
-    EXPECT_TRUE(root->GetList("list_with_empty_children", &inner));
-    EXPECT_EQ(1U, inner->GetSize());  // Dictionary was pruned.
-    EXPECT_TRUE(inner->GetList(0, &inner2));
-    EXPECT_EQ(1U, inner2->GetSize());
+
+    ListValue* inner_value, *inner_value2;
+    EXPECT_TRUE(root->GetList("list_with_empty_children", &inner_value));
+    EXPECT_EQ(1U, inner_value->GetSize());  // Dictionary was pruned.
+    EXPECT_TRUE(inner_value->GetList(0, &inner_value2));
+    EXPECT_EQ(1U, inner_value2->GetSize());
   }
 }
 
@@ -730,18 +747,18 @@
   scoped_ptr<DictionaryValue> base(new DictionaryValue);
   base->SetString("base_key", "base_key_value_base");
   base->SetString("collide_key", "collide_key_value_base");
-  DictionaryValue* base_sub_dict = new DictionaryValue;
+  scoped_ptr<DictionaryValue> base_sub_dict(new DictionaryValue);
   base_sub_dict->SetString("sub_base_key", "sub_base_key_value_base");
   base_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_base");
-  base->Set("sub_dict_key", base_sub_dict);
+  base->Set("sub_dict_key", base_sub_dict.Pass());
 
   scoped_ptr<DictionaryValue> merge(new DictionaryValue);
   merge->SetString("merge_key", "merge_key_value_merge");
   merge->SetString("collide_key", "collide_key_value_merge");
-  DictionaryValue* merge_sub_dict = new DictionaryValue;
+  scoped_ptr<DictionaryValue> merge_sub_dict(new DictionaryValue);
   merge_sub_dict->SetString("sub_merge_key", "sub_merge_key_value_merge");
   merge_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_merge");
-  merge->Set("sub_dict_key", merge_sub_dict);
+  merge->Set("sub_dict_key", merge_sub_dict.Pass());
 
   base->MergeDictionary(merge.get());
 
@@ -772,7 +789,8 @@
 }
 
 TEST(ValuesTest, MergeDictionaryDeepCopy) {
-  DictionaryValue* child = new DictionaryValue;
+  scoped_ptr<DictionaryValue> child(new DictionaryValue);
+  DictionaryValue* original_child = child.get();
   child->SetString("test", "value");
   EXPECT_EQ(1U, child->size());
 
@@ -781,22 +799,22 @@
   EXPECT_EQ("value", value);
 
   scoped_ptr<DictionaryValue> base(new DictionaryValue);
-  base->Set("dict", child);
+  base->Set("dict", child.Pass());
   EXPECT_EQ(1U, base->size());
 
   DictionaryValue* ptr;
   EXPECT_TRUE(base->GetDictionary("dict", &ptr));
-  EXPECT_EQ(child, ptr);
+  EXPECT_EQ(original_child, ptr);
 
   scoped_ptr<DictionaryValue> merged(new DictionaryValue);
   merged->MergeDictionary(base.get());
   EXPECT_EQ(1U, merged->size());
   EXPECT_TRUE(merged->GetDictionary("dict", &ptr));
-  EXPECT_NE(child, ptr);
+  EXPECT_NE(original_child, ptr);
   EXPECT_TRUE(ptr->GetString("test", &value));
   EXPECT_EQ("value", value);
 
-  child->SetString("test", "overwrite");
+  original_child->SetString("test", "overwrite");
   base.reset();
   EXPECT_TRUE(ptr->GetString("test", &value));
   EXPECT_EQ("value", value);
@@ -809,7 +827,7 @@
   }
 
   StringValue value1("value1");
-  dict.Set("key1", value1.DeepCopy());
+  dict.Set("key1", value1.CreateDeepCopy());
   bool seen1 = false;
   for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
     EXPECT_FALSE(seen1);
@@ -820,7 +838,7 @@
   EXPECT_TRUE(seen1);
 
   StringValue value2("value2");
-  dict.Set("key2", value2.DeepCopy());
+  dict.Set("key2", value2.CreateDeepCopy());
   bool seen2 = seen1 = false;
   for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
     if (it.key() == "key1") {
@@ -853,21 +871,21 @@
   DictionaryValue dict_value;
   ListValue list_value;
 
-  main_dict.Set("bool", bool_value.DeepCopy());
-  main_dict.Set("int", int_value.DeepCopy());
-  main_dict.Set("double", double_value.DeepCopy());
-  main_dict.Set("string", string_value.DeepCopy());
-  main_dict.Set("binary", binary_value.DeepCopy());
-  main_dict.Set("dict", dict_value.DeepCopy());
-  main_dict.Set("list", list_value.DeepCopy());
+  main_dict.Set("bool", bool_value.CreateDeepCopy());
+  main_dict.Set("int", int_value.CreateDeepCopy());
+  main_dict.Set("double", double_value.CreateDeepCopy());
+  main_dict.Set("string", string_value.CreateDeepCopy());
+  main_dict.Set("binary", binary_value.CreateDeepCopy());
+  main_dict.Set("dict", dict_value.CreateDeepCopy());
+  main_dict.Set("list", list_value.CreateDeepCopy());
 
-  main_list.Append(bool_value.DeepCopy());
-  main_list.Append(int_value.DeepCopy());
-  main_list.Append(double_value.DeepCopy());
-  main_list.Append(string_value.DeepCopy());
-  main_list.Append(binary_value.DeepCopy());
-  main_list.Append(dict_value.DeepCopy());
-  main_list.Append(list_value.DeepCopy());
+  main_list.Append(bool_value.CreateDeepCopy());
+  main_list.Append(int_value.CreateDeepCopy());
+  main_list.Append(double_value.CreateDeepCopy());
+  main_list.Append(string_value.CreateDeepCopy());
+  main_list.Append(binary_value.CreateDeepCopy());
+  main_list.Append(dict_value.CreateDeepCopy());
+  main_list.Append(list_value.CreateDeepCopy());
 
   EXPECT_TRUE(main_dict.Get("bool", NULL));
   EXPECT_TRUE(main_dict.Get("int", NULL));
diff --git a/base/win/memory_pressure_monitor.cc b/base/win/memory_pressure_monitor.cc
new file mode 100644
index 0000000..ed49a40
--- /dev/null
+++ b/base/win/memory_pressure_monitor.cc
@@ -0,0 +1,254 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/win/memory_pressure_monitor.h"
+
+#include <windows.h>
+
+#include "base/metrics/histogram_macros.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+
+namespace base {
+namespace win {
+
+namespace {
+
+static const DWORDLONG kMBBytes = 1024 * 1024;
+
+// Enumeration of UMA memory pressure levels. This needs to be kept in sync with
+// histograms.xml and the memory pressure levels defined in
+// MemoryPressureListener.
+enum MemoryPressureLevelUMA {
+  UMA_MEMORY_PRESSURE_LEVEL_NONE = 0,
+  UMA_MEMORY_PRESSURE_LEVEL_MODERATE = 1,
+  UMA_MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
+  // This must be the last value in the enum.
+  UMA_MEMORY_PRESSURE_LEVEL_COUNT,
+};
+
+// Converts a memory pressure level to an UMA enumeration value.
+MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
+    MemoryPressureListener::MemoryPressureLevel level) {
+  switch (level) {
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+      return UMA_MEMORY_PRESSURE_LEVEL_NONE;
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+      return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+      return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
+  }
+  NOTREACHED();
+  return UMA_MEMORY_PRESSURE_LEVEL_NONE;
+}
+
+}  // namespace
+
+// The following constants have been lifted from similar values in the ChromeOS
+// memory pressure monitor. The values were determined experimentally to ensure
+// sufficient responsiveness of the memory pressure subsystem, and minimal
+// overhead.
+const int MemoryPressureMonitor::kPollingIntervalMs = 5000;
+const int MemoryPressureMonitor::kModeratePressureCooldownMs = 10000;
+const int MemoryPressureMonitor::kModeratePressureCooldownCycles =
+    kModeratePressureCooldownMs / kPollingIntervalMs;
+
+// TODO(chrisha): Explore the following constants further with an experiment.
+
+// A system is considered 'high memory' if it has more than 1.5GB of system
+// memory available for use by the memory manager (not reserved for hardware
+// and drivers). This is a fuzzy version of the ~2GB discussed below.
+const int MemoryPressureMonitor::kLargeMemoryThresholdMb = 1536;
+
+// These are the default thresholds used for systems with < ~2GB of physical
+// memory. Such systems have been observed to always maintain ~100MB of
+// available memory, paging until that is the case. To try to avoid paging a
+// threshold slightly above this is chosen. The moderate threshold is slightly
+// less grounded in reality and chosen as 2.5x critical.
+const int MemoryPressureMonitor::kSmallMemoryDefaultModerateThresholdMb = 500;
+const int MemoryPressureMonitor::kSmallMemoryDefaultCriticalThresholdMb = 200;
+
+// These are the default thresholds used for systems with >= ~2GB of physical
+// memory. Such systems have been observed to always maintain ~300MB of
+// available memory, paging until that is the case.
+const int MemoryPressureMonitor::kLargeMemoryDefaultModerateThresholdMb = 1000;
+const int MemoryPressureMonitor::kLargeMemoryDefaultCriticalThresholdMb = 400;
+
+MemoryPressureMonitor::MemoryPressureMonitor()
+    : moderate_threshold_mb_(0),
+      critical_threshold_mb_(0),
+      current_memory_pressure_level_(
+          MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
+      moderate_pressure_repeat_count_(0),
+      weak_ptr_factory_(this) {
+  InferThresholds();
+  StartObserving();
+}
+
+MemoryPressureMonitor::MemoryPressureMonitor(int moderate_threshold_mb,
+                                             int critical_threshold_mb)
+    : moderate_threshold_mb_(moderate_threshold_mb),
+      critical_threshold_mb_(critical_threshold_mb),
+      current_memory_pressure_level_(
+          MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
+      moderate_pressure_repeat_count_(0),
+      weak_ptr_factory_(this) {
+  DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_);
+  DCHECK_LE(0, critical_threshold_mb_);
+  StartObserving();
+}
+
+MemoryPressureMonitor::~MemoryPressureMonitor() {
+  StopObserving();
+}
+
+void MemoryPressureMonitor::CheckMemoryPressureSoon() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, Bind(&MemoryPressureMonitor::CheckMemoryPressure,
+                      weak_ptr_factory_.GetWeakPtr()));
+}
+
+MemoryPressureListener::MemoryPressureLevel
+MemoryPressureMonitor::GetCurrentPressureLevel() const {
+  return current_memory_pressure_level_;
+}
+
+void MemoryPressureMonitor::InferThresholds() {
+  // Default to a 'high' memory situation, which uses more conservative
+  // thresholds.
+  bool high_memory = true;
+  MEMORYSTATUSEX mem_status = {};
+  if (GetSystemMemoryStatus(&mem_status)) {
+    static const DWORDLONG kLargeMemoryThresholdBytes =
+        static_cast<DWORDLONG>(kLargeMemoryThresholdMb) * kMBBytes;
+    high_memory = mem_status.ullTotalPhys >= kLargeMemoryThresholdBytes;
+  }
+
+  if (high_memory) {
+    moderate_threshold_mb_ = kLargeMemoryDefaultModerateThresholdMb;
+    critical_threshold_mb_ = kLargeMemoryDefaultCriticalThresholdMb;
+  } else {
+    moderate_threshold_mb_ = kSmallMemoryDefaultModerateThresholdMb;
+    critical_threshold_mb_ = kSmallMemoryDefaultCriticalThresholdMb;
+  }
+}
+
+void MemoryPressureMonitor::StartObserving() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  timer_.Start(FROM_HERE,
+               TimeDelta::FromMilliseconds(kPollingIntervalMs),
+               Bind(&MemoryPressureMonitor::
+                        CheckMemoryPressureAndRecordStatistics,
+                    weak_ptr_factory_.GetWeakPtr()));
+}
+
+void MemoryPressureMonitor::StopObserving() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // If StartObserving failed, StopObserving will still get called.
+  timer_.Stop();
+  weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
+void MemoryPressureMonitor::CheckMemoryPressure() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // Get the previous pressure level and update the current one.
+  MemoryPressureLevel old_pressure = current_memory_pressure_level_;
+  current_memory_pressure_level_ = CalculateCurrentPressureLevel();
+
+  // |notify| will be set to true if MemoryPressureListeners need to be
+  // notified of a memory pressure level state change.
+  bool notify = false;
+  switch (current_memory_pressure_level_) {
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+      break;
+
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+      if (old_pressure != current_memory_pressure_level_) {
+        // This is a new transition to moderate pressure so notify.
+        moderate_pressure_repeat_count_ = 0;
+        notify = true;
+      } else {
+        // Already in moderate pressure, only notify if sustained over the
+        // cooldown period.
+        if (++moderate_pressure_repeat_count_ ==
+                kModeratePressureCooldownCycles) {
+          moderate_pressure_repeat_count_ = 0;
+          notify = true;
+        }
+      }
+      break;
+
+    case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+      // Always notify of critical pressure levels.
+      notify = true;
+      break;
+  }
+
+  if (!notify)
+    return;
+
+  // Emit a notification of the current memory pressure level. This can only
+  // happen for moderate and critical pressure levels.
+  DCHECK_NE(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+            current_memory_pressure_level_);
+  MemoryPressureListener::NotifyMemoryPressure(current_memory_pressure_level_);
+}
+
+void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  CheckMemoryPressure();
+
+  UMA_HISTOGRAM_ENUMERATION(
+      "Memory.PressureLevel",
+      MemoryPressureLevelToUmaEnumValue(current_memory_pressure_level_),
+      UMA_MEMORY_PRESSURE_LEVEL_COUNT);
+}
+
+MemoryPressureListener::MemoryPressureLevel
+MemoryPressureMonitor::CalculateCurrentPressureLevel() {
+  MEMORYSTATUSEX mem_status = {};
+  if (!GetSystemMemoryStatus(&mem_status))
+    return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
+
+  // How much system memory is actively available for use right now, in MBs.
+  int phys_free = static_cast<int>(mem_status.ullAvailPhys / kMBBytes);
+
+  // TODO(chrisha): This should eventually care about address space pressure,
+  // but the browser process (where this is running) effectively never runs out
+  // of address space. Renderers occasionally do, but it does them no good to
+  // have the browser process monitor address space pressure. Long term,
+  // renderers should run their own address space pressure monitors and act
+  // accordingly, with the browser making cross-process decisions based on
+  // system memory pressure.
+
+  // Determine if the physical memory is under critical memory pressure.
+  if (phys_free <= critical_threshold_mb_)
+    return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
+
+  // Determine if the physical memory is under moderate memory pressure.
+  if (phys_free <= moderate_threshold_mb_)
+    return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
+
+  // No memory pressure was detected.
+  return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
+}
+
+bool MemoryPressureMonitor::GetSystemMemoryStatus(
+    MEMORYSTATUSEX* mem_status) {
+  DCHECK(mem_status != nullptr);
+  mem_status->dwLength = sizeof(*mem_status);
+  if (!::GlobalMemoryStatusEx(mem_status))
+    return false;
+  return true;
+}
+
+}  // namespace win
+}  // namespace base
diff --git a/base/win/memory_pressure_monitor.h b/base/win/memory_pressure_monitor.h
new file mode 100644
index 0000000..933d912
--- /dev/null
+++ b/base/win/memory_pressure_monitor.h
@@ -0,0 +1,144 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_WIN_MEMORY_PRESSURE_MONITOR_H_
+#define BASE_WIN_MEMORY_PRESSURE_MONITOR_H_
+
+#include "base/base_export.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/memory_pressure_monitor.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "base/timer/timer.h"
+
+// To not pull in windows.h.
+typedef struct _MEMORYSTATUSEX MEMORYSTATUSEX;
+
+namespace base {
+namespace win {
+
+// Windows memory pressure monitor. Because there is no OS provided signal this
+// polls at a low frequency (once per second), and applies internal hysteresis.
+class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
+ public:
+  // Constants governing the polling and hysteresis behaviour of the observer.
+
+  // The polling interval, in milliseconds. While under critical pressure, this
+  // is also the timer to repeat cleanup attempts.
+  static const int kPollingIntervalMs;
+  // The time which should pass between 2 successive moderate memory pressure
+  // signals, in milliseconds.
+  static const int kModeratePressureCooldownMs;
+  // The number of cycles that should pass between 2 successive moderate memory
+  // pressure signals.
+  static const int kModeratePressureCooldownCycles;
+
+  // Constants governing the memory pressure level detection.
+
+  // The amount of total system memory beyond which a system is considered to be
+  // a large-memory system.
+  static const int kLargeMemoryThresholdMb;
+  // Default minimum free memory thresholds for small-memory systems, in MB.
+  static const int kSmallMemoryDefaultModerateThresholdMb;
+  static const int kSmallMemoryDefaultCriticalThresholdMb;
+  // Default minimum free memory thresholds for large-memory systems, in MB.
+  static const int kLargeMemoryDefaultModerateThresholdMb;
+  static const int kLargeMemoryDefaultCriticalThresholdMb;
+
+  // Default constructor. Will choose thresholds automatically basd on the
+  // actual amount of system memory.
+  MemoryPressureMonitor();
+
+  // Constructor with explicit memory thresholds. These represent the amount of
+  // free memory below which the applicable memory pressure state engages.
+  MemoryPressureMonitor(int moderate_threshold_mb, int critical_threshold_mb);
+
+  ~MemoryPressureMonitor() override;
+
+  // Schedules a memory pressure check to run soon. This must be called on the
+  // same thread where the monitor was instantiated.
+  void CheckMemoryPressureSoon();
+
+  // Get the current memory pressure level. This can be called from any thread.
+  MemoryPressureLevel GetCurrentPressureLevel() const override;
+
+  // Returns the moderate pressure level free memory threshold, in MB.
+  int moderate_threshold_mb() const { return moderate_threshold_mb_; }
+
+  // Returns the critical pressure level free memory threshold, in MB.
+  int critical_threshold_mb() const { return critical_threshold_mb_; }
+
+ protected:
+  // Internals are exposed for unittests.
+
+  // Automatically infers threshold values based on system memory. This invokes
+  // GetMemoryStatus so it can be mocked in unittests.
+  void InferThresholds();
+
+  // Starts observing the memory fill level. Calls to StartObserving should
+  // always be matched with calls to StopObserving.
+  void StartObserving();
+
+  // Stop observing the memory fill level. May be safely called if
+  // StartObserving has not been called. Must be called from the same thread on
+  // which the monitor was instantiated.
+  void StopObserving();
+
+  // Checks memory pressure, storing the current level, applying any hysteresis
+  // and emitting memory pressure level change signals as necessary. This
+  // function is called periodically while the monitor is observing memory
+  // pressure. This is split out from CheckMemoryPressureAndRecordStatistics so
+  // that it may be called by CheckMemoryPressureSoon and not invoke UMA
+  // logging. Must be called from the same thread on which the monitor was
+  // instantiated.
+  void CheckMemoryPressure();
+
+  // Wrapper to CheckMemoryPressure that also records the observed memory
+  // pressure level via an UMA enumeration. This is the function that is called
+  // periodically by the timer. Must be called from the same thread on which the
+  // monitor was instantiated.
+  void CheckMemoryPressureAndRecordStatistics();
+
+  // Calculates the current instantaneous memory pressure level. This does not
+  // use any hysteresis and simply returns the result at the current moment. Can
+  // be called on any thread.
+  MemoryPressureLevel CalculateCurrentPressureLevel();
+
+  // Gets system memory status. This is virtual as a unittesting hook. Returns
+  // true if the system call succeeds, false otherwise. Can be called on any
+  // thread.
+  virtual bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status);
+
+ private:
+  // Threshold amounts of available memory that trigger pressure levels. See
+  // memory_pressure_monitor.cc for a discussion of reasonable values for these.
+  int moderate_threshold_mb_;
+  int critical_threshold_mb_;
+
+  // A periodic timer to check for memory pressure changes.
+  base::RepeatingTimer<MemoryPressureMonitor> timer_;
+
+  // The current memory pressure.
+  MemoryPressureLevel current_memory_pressure_level_;
+
+  // To slow down the amount of moderate pressure event calls, this gets used to
+  // count the number of events since the last event occured. This is used by
+  // |CheckMemoryPressure| to apply hysteresis on the raw results of
+  // |CalculateCurrentPressureLevel|.
+  int moderate_pressure_repeat_count_;
+
+  // Ensures that this object is used from a single thread.
+  base::ThreadChecker thread_checker_;
+
+  // Weak pointer factory to ourself used for scheduling calls to
+  // CheckMemoryPressure/CheckMemoryPressureAndRecordStatistics via |timer_|.
+  base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
+};
+
+}  // namespace win
+}  // namespace base
+
+#endif  // BASE_WIN_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/win/memory_pressure_monitor_unittest.cc b/base/win/memory_pressure_monitor_unittest.cc
new file mode 100644
index 0000000..40a25a7
--- /dev/null
+++ b/base/win/memory_pressure_monitor_unittest.cc
@@ -0,0 +1,298 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/win/memory_pressure_monitor.h"
+
+#include "base/basictypes.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/message_loop/message_loop.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace win {
+
+namespace {
+
+struct PressureSettings {
+  int phys_left_mb;
+  MemoryPressureListener::MemoryPressureLevel level;
+};
+
+}  // namespace
+
+// This is outside of the anonymous namespace so that it can be seen as a friend
+// to the monitor class.
+class TestMemoryPressureMonitor : public MemoryPressureMonitor {
+ public:
+  using MemoryPressureMonitor::CalculateCurrentPressureLevel;
+  using MemoryPressureMonitor::CheckMemoryPressure;
+
+  static const DWORDLONG kMBBytes = 1024 * 1024;
+
+  explicit TestMemoryPressureMonitor(bool large_memory)
+      : mem_status_() {
+    // Generate a plausible amount of memory.
+    mem_status_.ullTotalPhys =
+        static_cast<DWORDLONG>(GenerateTotalMemoryMb(large_memory)) * kMBBytes;
+
+    // Rerun InferThresholds using the test fixture's GetSystemMemoryStatus.
+    InferThresholds();
+    // Stop the timer.
+    StopObserving();
+  }
+
+  TestMemoryPressureMonitor(int system_memory_mb,
+                            int moderate_threshold_mb,
+                            int critical_threshold_mb)
+      : MemoryPressureMonitor(moderate_threshold_mb, critical_threshold_mb),
+        mem_status_() {
+    // Set the amount of system memory.
+    mem_status_.ullTotalPhys = static_cast<DWORDLONG>(
+        system_memory_mb * kMBBytes);
+
+    // Stop the timer.
+    StopObserving();
+  }
+
+  virtual ~TestMemoryPressureMonitor() {}
+
+  MOCK_METHOD1(OnMemoryPressure,
+               void(MemoryPressureListener::MemoryPressureLevel level));
+
+  // Generates an amount of total memory that is consistent with the requested
+  // memory model.
+  int GenerateTotalMemoryMb(bool large_memory) {
+    int total_mb = 64;
+    while (total_mb < MemoryPressureMonitor::kLargeMemoryThresholdMb)
+      total_mb *= 2;
+    if (large_memory)
+      return total_mb * 2;
+    return total_mb / 2;
+  }
+
+  // Sets up the memory status to reflect the provided absolute memory left.
+  void SetMemoryFree(int phys_left_mb) {
+    // ullTotalPhys is set in the constructor and not modified.
+
+    // Set the amount of available memory.
+    mem_status_.ullAvailPhys =
+        static_cast<DWORDLONG>(phys_left_mb) * kMBBytes;
+    DCHECK_LT(mem_status_.ullAvailPhys, mem_status_.ullTotalPhys);
+
+    // These fields are unused.
+    mem_status_.dwMemoryLoad = 0;
+    mem_status_.ullTotalPageFile = 0;
+    mem_status_.ullAvailPageFile = 0;
+    mem_status_.ullTotalVirtual = 0;
+    mem_status_.ullAvailVirtual = 0;
+  }
+
+  void SetNone() {
+    SetMemoryFree(moderate_threshold_mb() + 1);
+  }
+
+  void SetModerate() {
+    SetMemoryFree(moderate_threshold_mb() - 1);
+  }
+
+  void SetCritical() {
+    SetMemoryFree(critical_threshold_mb() - 1);
+  }
+
+ private:
+  bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status) override {
+    // Simply copy the memory status set by the test fixture.
+    *mem_status = mem_status_;
+    return true;
+  }
+
+  MEMORYSTATUSEX mem_status_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
+};
+
+class WinMemoryPressureMonitorTest : public testing::Test {
+ protected:
+  void CalculateCurrentMemoryPressureLevelTest(
+      TestMemoryPressureMonitor* monitor) {
+
+    int mod = monitor->moderate_threshold_mb();
+    monitor->SetMemoryFree(mod + 1);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+              monitor->CalculateCurrentPressureLevel());
+
+    monitor->SetMemoryFree(mod);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+              monitor->CalculateCurrentPressureLevel());
+
+    monitor->SetMemoryFree(mod - 1);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+              monitor->CalculateCurrentPressureLevel());
+
+    int crit = monitor->critical_threshold_mb();
+    monitor->SetMemoryFree(crit + 1);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+              monitor->CalculateCurrentPressureLevel());
+
+    monitor->SetMemoryFree(crit);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
+              monitor->CalculateCurrentPressureLevel());
+
+    monitor->SetMemoryFree(crit - 1);
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
+              monitor->CalculateCurrentPressureLevel());
+  }
+
+  base::MessageLoopForUI message_loop_;
+};
+
+// Tests the fundamental direct calculation of memory pressure with automatic
+// small-memory thresholds.
+TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelSmall) {
+  static const int kModerateMb =
+      MemoryPressureMonitor::kSmallMemoryDefaultModerateThresholdMb;
+  static const int kCriticalMb =
+      MemoryPressureMonitor::kSmallMemoryDefaultCriticalThresholdMb;
+
+  TestMemoryPressureMonitor monitor(false);  // Small-memory model.
+
+  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
+  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
+
+  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
+}
+
+// Tests the fundamental direct calculation of memory pressure with automatic
+// large-memory thresholds.
+TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelLarge) {
+  static const int kModerateMb =
+      MemoryPressureMonitor::kLargeMemoryDefaultModerateThresholdMb;
+  static const int kCriticalMb =
+      MemoryPressureMonitor::kLargeMemoryDefaultCriticalThresholdMb;
+
+  TestMemoryPressureMonitor monitor(true);  // Large-memory model.
+
+  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
+  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
+
+  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
+}
+
+// Tests the fundamental direct calculation of memory pressure with manually
+// specified threshold levels.
+TEST_F(WinMemoryPressureMonitorTest,
+       CalculateCurrentMemoryPressureLevelCustom) {
+  static const int kSystemMb = 512;
+  static const int kModerateMb = 256;
+  static const int kCriticalMb = 128;
+
+  TestMemoryPressureMonitor monitor(kSystemMb, kModerateMb, kCriticalMb);
+
+  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
+  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
+
+  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
+}
+
+// This test tests the various transition states from memory pressure, looking
+// for the correct behavior on event reposting as well as state updates.
+TEST_F(WinMemoryPressureMonitorTest, CheckMemoryPressure) {
+  // Large-memory.
+  testing::StrictMock<TestMemoryPressureMonitor> monitor(true);
+  MemoryPressureListener listener(
+      base::Bind(&TestMemoryPressureMonitor::OnMemoryPressure,
+                 base::Unretained(&monitor)));
+
+  // Checking the memory pressure at 0% load should not produce any
+  // events.
+  monitor.SetNone();
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+            monitor.GetCurrentPressureLevel());
+
+  // Setting the memory level to 80% should produce a moderate pressure level.
+  EXPECT_CALL(monitor,
+              OnMemoryPressure(MemoryPressureListener::
+                                   MEMORY_PRESSURE_LEVEL_MODERATE));
+  monitor.SetModerate();
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+            monitor.GetCurrentPressureLevel());
+  testing::Mock::VerifyAndClearExpectations(&monitor);
+
+  // Check that the event gets reposted after a while.
+  for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
+    if (i + 1 == monitor.kModeratePressureCooldownCycles) {
+      EXPECT_CALL(monitor,
+                  OnMemoryPressure(MemoryPressureListener::
+                                       MEMORY_PRESSURE_LEVEL_MODERATE));
+    }
+    monitor.CheckMemoryPressure();
+    message_loop_.RunUntilIdle();
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+              monitor.GetCurrentPressureLevel());
+    testing::Mock::VerifyAndClearExpectations(&monitor);
+  }
+
+  // Setting the memory usage to 99% should produce critical levels.
+  EXPECT_CALL(monitor,
+              OnMemoryPressure(MemoryPressureListener::
+                                   MEMORY_PRESSURE_LEVEL_CRITICAL));
+  monitor.SetCritical();
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
+            monitor.GetCurrentPressureLevel());
+  testing::Mock::VerifyAndClearExpectations(&monitor);
+
+  // Calling it again should immediately produce a second call.
+  EXPECT_CALL(monitor,
+              OnMemoryPressure(MemoryPressureListener::
+                                   MEMORY_PRESSURE_LEVEL_CRITICAL));
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
+            monitor.GetCurrentPressureLevel());
+  testing::Mock::VerifyAndClearExpectations(&monitor);
+
+  // When lowering the pressure again there should be a notification and the
+  // pressure should go back to moderate.
+  EXPECT_CALL(monitor,
+              OnMemoryPressure(MemoryPressureListener::
+                                   MEMORY_PRESSURE_LEVEL_MODERATE));
+  monitor.SetModerate();
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+            monitor.GetCurrentPressureLevel());
+  testing::Mock::VerifyAndClearExpectations(&monitor);
+
+  // Check that the event gets reposted after a while.
+  for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
+    if (i + 1 == monitor.kModeratePressureCooldownCycles) {
+      EXPECT_CALL(monitor,
+                  OnMemoryPressure(MemoryPressureListener::
+                                       MEMORY_PRESSURE_LEVEL_MODERATE));
+    }
+    monitor.CheckMemoryPressure();
+    message_loop_.RunUntilIdle();
+    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+              monitor.GetCurrentPressureLevel());
+    testing::Mock::VerifyAndClearExpectations(&monitor);
+  }
+
+  // Going down to no pressure should not produce an notification.
+  monitor.SetNone();
+  monitor.CheckMemoryPressure();
+  message_loop_.RunUntilIdle();
+  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+            monitor.GetCurrentPressureLevel());
+  testing::Mock::VerifyAndClearExpectations(&monitor);
+}
+
+}  // namespace win
+}  // namespace base
diff --git a/base/win/resource_util.h b/base/win/resource_util.h
index f3444ae..8a8baa0 100644
--- a/base/win/resource_util.h
+++ b/base/win/resource_util.h
@@ -5,8 +5,8 @@
 // This file contains utility functions for accessing resources in external
 // files (DLLs) or embedded in the executable itself.
 
-#ifndef BASE_WIN_RESOURCE_UTIL_H__
-#define BASE_WIN_RESOURCE_UTIL_H__
+#ifndef BASE_WIN_RESOURCE_UTIL_H_
+#define BASE_WIN_RESOURCE_UTIL_H_
 
 #include <windows.h>
 
@@ -36,4 +36,4 @@
 }  // namespace win
 }  // namespace base
 
-#endif  // BASE_WIN_RESOURCE_UTIL_H__
+#endif  // BASE_WIN_RESOURCE_UTIL_H_
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index 33a8aa5..ce944e4 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -132,10 +132,6 @@
   // This lock only protects against races in this module, which is fine.
   AutoNativeLock lock(g_lock.Get());
   g_active_verifier = verifier ? verifier : new ActiveVerifier(true);
-
-  // TODO(shrikant): Enable handle verifier after figuring out
-  // AppContainer/DuplicateHandle error.
-  g_active_verifier->Disable();
 #endif
 }
 
@@ -156,6 +152,12 @@
   if (!enabled_)
     return;
 
+  // Idea here is to make our handles non-closable until we close it ourselves.
+  // Handles provided could be totally fabricated especially through our
+  // unittest, we are ignoring that for now by not checking return value.
+  ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE,
+                         HANDLE_FLAG_PROTECT_FROM_CLOSE);
+
   // Grab the thread id before the lock.
   DWORD thread_id = GetCurrentThreadId();
 
@@ -176,6 +178,15 @@
   if (!enabled_)
     return;
 
+  // We expect handle to be protected till this point.
+  DWORD flags = 0;
+  if (::GetHandleInformation(handle, &flags)) {
+    CHECK_NE(0U, (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE));
+
+    // Unprotect handle so that it could be closed.
+    ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
+  }
+
   AutoNativeLock lock(*lock_);
   HandleMap::iterator i = map_.find(handle);
   if (i == map_.end())
diff --git a/base/win/startup_information.h b/base/win/startup_information.h
index 73d9f3e..3f18ee5 100644
--- a/base/win/startup_information.h
+++ b/base/win/startup_information.h
@@ -47,4 +47,4 @@
 }  // namespace win
 }  // namespace base
 
-#endif  // BASE_WIN_STARTUP_INFORMATION_H__
+#endif  // BASE_WIN_STARTUP_INFORMATION_H_