Update from https://crrev.com/320931
- Add IsFlat() definition to ui/gfx/transform
- Change sky's uses of skia's FilterLevel to FilterQuality
- Update cc_strip_video.patch

R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/1013463003
diff --git a/BUILD.gn b/BUILD.gn
index 69f366e..f103446 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,6 +9,10 @@
   import("//build/config/android/rules.gni")
 }
 
+config("base_implementation") {
+  defines = [ "BASE_IMPLEMENTATION" ]
+}
+
 source_set("base_paths") {
   sources = [
     "base_paths.cc",
@@ -34,7 +38,7 @@
     ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ ":base_implementation" ]
 
   deps = [
     "//base/memory",
@@ -607,7 +611,7 @@
     "sys_info_openbsd.cc",
   ]
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ ":base_implementation" ]
 
   deps = [
     ":base_static",
@@ -630,7 +634,7 @@
   # Allow more direct string conversions on platforms with native utf8
   # strings
   if (is_mac || is_ios || is_chromeos) {
-    defines += [ "SYSTEM_NATIVE_UTF8" ]
+    defines = [ "SYSTEM_NATIVE_UTF8" ]
   }
 
   if (is_android) {
@@ -758,12 +762,9 @@
     configs += linux_configs
     all_dependent_configs = linux_configs
 
-    defines += [ "USE_SYMBOLIZE" ]
-
     # These dependencies are not required on Android, and in the case
     # of xdg_mime must be excluded due to licensing restrictions.
     deps += [
-      "//base/third_party/symbolize",
       "//base/third_party/xdg_mime",
       "//base/third_party/xdg_user_dirs",
     ]
@@ -1135,7 +1136,6 @@
     "mac/scoped_sending_event_unittest.mm",
     "md5_unittest.cc",
     "memory/aligned_memory_unittest.cc",
-    "memory/discardable_memory_unittest.cc",
     "memory/discardable_shared_memory_unittest.cc",
     "memory/linked_ptr_unittest.cc",
     "memory/ref_counted_memory_unittest.cc",
@@ -1283,8 +1283,6 @@
     "win/wrapped_window_proc_unittest.cc",
   ]
 
-  defines = []
-
   deps = [
     ":base",
     ":i18n",
@@ -1304,7 +1302,7 @@
   # Allow more direct string conversions on platforms with native utf8
   # strings
   if (is_mac || is_ios || is_chromeos) {
-    defines += [ "SYSTEM_NATIVE_UTF8" ]
+    defines = [ "SYSTEM_NATIVE_UTF8" ]
   }
 
   if (is_android) {
@@ -1341,7 +1339,6 @@
   if (is_linux) {
     sources -= [ "file_version_info_unittest.cc" ]
     sources += [ "nix/xdg_util_unittest.cc" ]
-    defines += [ "USE_SYMBOLIZE" ]
     if (use_glib) {
       configs += [ "//build/config/linux:glib" ]
     }
diff --git a/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index c7d8527..484c6bc 100644
--- a/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -5,6 +5,8 @@
 package org.chromium.base.library_loader;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.AsyncTask;
 import android.os.SystemClock;
 import android.util.Log;
 
@@ -13,6 +15,13 @@
 import org.chromium.base.JNINamespace;
 import org.chromium.base.TraceEvent;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
 import java.util.Locale;
 
 import javax.annotation.Nullable;
@@ -87,6 +96,9 @@
     // final (like now) or be protected in some way (volatile of synchronized).
     private final int mLibraryProcessType;
 
+    // Library -> Path it has been loaded from.
+    private final HashMap<String, String> mLoadedFrom;
+
     /**
      * @param libraryProcessType the process the shared library is loaded in. refer to
      *                           LibraryProcessType for possible values.
@@ -106,6 +118,7 @@
 
     private LibraryLoader(int libraryProcessType) {
         mLibraryProcessType = libraryProcessType;
+        mLoadedFrom = new HashMap<String, String>();
     }
 
     /**
@@ -189,6 +202,68 @@
         }
     }
 
+    private void prefetchLibraryToMemory(Context context, String library) {
+        String libFilePath = mLoadedFrom.get(library);
+        if (libFilePath == null) {
+            Log.i(TAG, "File path not found for " + library);
+            return;
+        }
+        String apkFilePath = context.getApplicationInfo().sourceDir;
+        if (libFilePath.equals(apkFilePath)) {
+            // TODO(lizeb): Make pre-faulting work with libraries loaded from the APK.
+            return;
+        }
+        try {
+            TraceEvent.begin("LibraryLoader.prefetchLibraryToMemory");
+            File file = new File(libFilePath);
+            int size = (int) file.length();
+            FileChannel channel = new RandomAccessFile(file, "r").getChannel();
+            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
+            // TODO(lizeb): Figure out whether walking the entire library is really necessary.
+            // Page size is 4096 for all current Android architectures.
+            for (int index = 0; index < size; index += 4096) {
+                // Note: Testing shows that neither the Java compiler nor
+                // Dalvik/ART eliminates this loop.
+                buffer.get(index);
+            }
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "Library file not found: " + e);
+        } catch (IOException e) {
+            Log.w(TAG, "Impossible to map the file: " + e);
+        } finally {
+            TraceEvent.end("LibraryLoader.prefetchLibraryToMemory");
+        }
+    }
+
+    /** Prefetches the native libraries in a background thread.
+     *
+     * Launches an AsyncTask that maps the native libraries into memory, reads a
+     * part of each page from it, than unmaps it. This is done to warm up the
+     * page cache, turning hard page faults into soft ones.
+     *
+     * This is done this way, as testing shows that fadvise(FADV_WILLNEED) is
+     * detrimental to the startup time.
+     *
+     * @param context the application context.
+     */
+    public void asyncPrefetchLibrariesToMemory(final Context context) {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                // Note: AsyncTasks are executed in a low priority background
+                // thread, which is the desired behavior here since we don't
+                // want to interfere with the rest of the initialization.
+                for (String library : NativeLibraries.LIBRARIES) {
+                    if (Linker.isChromiumLinkerLibrary(library)) {
+                        continue;
+                    }
+                    prefetchLibraryToMemory(context, library);
+                }
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
     // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code
     private void loadAlreadyLocked(
             Context context, boolean shouldDeleteFallbackLibraries)
@@ -263,6 +338,7 @@
                                                 ? "using no map executable support fallback"
                                                 : "directly")
                                         + " from within " + apkFilePath);
+                                mLoadedFrom.put(library, apkFilePath);
                             } else {
                                 // Unpack library fallback.
                                 Log.i(TAG, "Loading " + library
@@ -272,10 +348,14 @@
                                         context, library);
                                 fallbackWasUsed = true;
                                 Log.i(TAG, "Built fallback library " + libFilePath);
+                                mLoadedFrom.put(library, libFilePath);
                             }
                         } else {
                             // The library is in its own file.
                             Log.i(TAG, "Loading " + library);
+                            ApplicationInfo applicationInfo = context.getApplicationInfo();
+                            mLoadedFrom.put(library, new File(applicationInfo.nativeLibraryDir,
+                                                              libFilePath).getAbsolutePath());
                         }
 
                         // Load the library.
diff --git a/android/java/src/org/chromium/base/metrics/RecordHistogram.java b/android/java/src/org/chromium/base/metrics/RecordHistogram.java
index 08c314f..c1f6d36 100644
--- a/android/java/src/org/chromium/base/metrics/RecordHistogram.java
+++ b/android/java/src/org/chromium/base/metrics/RecordHistogram.java
@@ -43,6 +43,16 @@
     }
 
     /**
+     * Records a sample in a count histogram of the given name. This is the Java equivalent of the
+     * UMA_HISTOGRAM_COUNTS C++ macro.
+     * @param name name of the histogram
+     * @param sample sample to be recorded, at least 1 and at most 999999
+     */
+    public static void recordCountHistogram(String name, int sample) {
+        nativeRecordCountHistogram(name, System.identityHashCode(name), sample);
+    }
+
+    /**
      * Records a sample in a histogram of times. Useful for recording short durations. This is the
      * Java equivalent of the UMA_HISTOGRAM_TIMES C++ macro.
      * @param name name of the histogram
@@ -123,6 +133,7 @@
     private static native void nativeRecordBooleanHistogram(String name, int key, boolean sample);
     private static native void nativeRecordEnumeratedHistogram(
             String name, int key, int sample, int boundary);
+    private static native void nativeRecordCountHistogram(String name, int key, int sample);
 
     private static native int nativeGetHistogramValueCountForTesting(String name, int sample);
     private static native void nativeInitialize();
diff --git a/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java b/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java
index f0489d3..24af056 100644
--- a/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java
+++ b/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java
@@ -80,6 +80,47 @@
     }
 
     /**
+     * Tests recording of count histograms.
+     */
+    @SmallTest
+    public void testRecordCountHistogram() {
+        String histogram = "HelloWorld.CountMetric";
+        HistogramDelta zeroCount = new HistogramDelta(histogram, 0);
+        HistogramDelta oneCount = new HistogramDelta(histogram, 1);
+        HistogramDelta twoCount = new HistogramDelta(histogram, 2);
+        HistogramDelta eightThousandCount = new HistogramDelta(histogram, 8000);
+
+        assertEquals(0, zeroCount.getDelta());
+        assertEquals(0, oneCount.getDelta());
+        assertEquals(0, twoCount.getDelta());
+        assertEquals(0, eightThousandCount.getDelta());
+
+        RecordHistogram.recordCountHistogram(histogram, 0);
+        assertEquals(1, zeroCount.getDelta());
+        assertEquals(0, oneCount.getDelta());
+        assertEquals(0, twoCount.getDelta());
+        assertEquals(0, eightThousandCount.getDelta());
+
+        RecordHistogram.recordCountHistogram(histogram, 0);
+        assertEquals(2, zeroCount.getDelta());
+        assertEquals(0, oneCount.getDelta());
+        assertEquals(0, twoCount.getDelta());
+        assertEquals(0, eightThousandCount.getDelta());
+
+        RecordHistogram.recordCountHistogram(histogram, 2);
+        assertEquals(2, zeroCount.getDelta());
+        assertEquals(0, oneCount.getDelta());
+        assertEquals(1, twoCount.getDelta());
+        assertEquals(0, eightThousandCount.getDelta());
+
+        RecordHistogram.recordCountHistogram(histogram, 8000);
+        assertEquals(2, zeroCount.getDelta());
+        assertEquals(0, oneCount.getDelta());
+        assertEquals(1, twoCount.getDelta());
+        assertEquals(1, eightThousandCount.getDelta());
+    }
+
+    /**
      * Tests recording of custom times histograms.
      */
     @SmallTest
diff --git a/android/jni_android.cc b/android/jni_android.cc
index a2de00a..1b715dc 100644
--- a/android/jni_android.cc
+++ b/android/jni_android.cc
@@ -159,10 +159,25 @@
 ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
   jclass clazz;
   if (!g_class_loader.Get().is_null()) {
+    // ClassLoader.loadClass expects a classname with components separated by
+    // dots instead of the slashes that JNIEnv::FindClass expects. The JNI
+    // generator generates names with slashes, so we have to replace them here.
+    // TODO(torne): move to an approach where we always use ClassLoader except
+    // for the special case of base::android::GetClassLoader(), and change the
+    // JNI generator to generate dot-separated names. http://crbug.com/461773
+    size_t bufsize = strlen(class_name) + 1;
+    char dotted_name[bufsize];
+    memmove(dotted_name, class_name, bufsize);
+    for (size_t i = 0; i < bufsize; ++i) {
+      if (dotted_name[i] == '/') {
+        dotted_name[i] = '.';
+      }
+    }
+
     clazz = static_cast<jclass>(
         env->CallObjectMethod(g_class_loader.Get().obj(),
                               g_class_loader_load_class_method_id,
-                              ConvertUTF8ToJavaString(env, class_name).obj()));
+                              ConvertUTF8ToJavaString(env, dotted_name).obj()));
   } else {
     clazz = env->FindClass(class_name);
   }
diff --git a/android/record_histogram.cc b/android/record_histogram.cc
index 0df0487..8b7f7bd 100644
--- a/android/record_histogram.cc
+++ b/android/record_histogram.cc
@@ -60,6 +60,31 @@
     return InsertLocked(j_histogram_key, histogram);
   }
 
+  HistogramBase* CountHistogram(JNIEnv* env,
+                                jstring j_histogram_name,
+                                jint j_histogram_key) {
+    // These values are based on the hard-coded constants in the
+    // UMA_HISTOGRAM_COUNTS macro from base/metrics/histogram_macros.h.
+    const int histogram_min = 1;
+    const int histogram_max = 1000000;
+    const int histogram_num_buckets = 50;
+
+    DCHECK(j_histogram_name);
+    DCHECK(j_histogram_key);
+    HistogramBase* histogram = FindLocked(j_histogram_key);
+    if (histogram) {
+      DCHECK(histogram->HasConstructionArguments(histogram_min, histogram_max,
+                                                 histogram_num_buckets));
+      return histogram;
+    }
+
+    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
+    histogram = Histogram::FactoryGet(histogram_name, histogram_min,
+                                      histogram_max, histogram_num_buckets,
+                                      HistogramBase::kUmaTargetedHistogramFlag);
+    return InsertLocked(j_histogram_key, histogram);
+  }
+
   HistogramBase* CustomTimesHistogram(JNIEnv* env,
                                       jstring j_histogram_name,
                                       jint j_histogram_key,
@@ -133,6 +158,18 @@
       ->Add(sample);
 }
 
+void RecordCountHistogram(JNIEnv* env,
+                          jclass clazz,
+                          jstring j_histogram_name,
+                          jint j_histogram_key,
+                          jint j_sample) {
+  int sample = static_cast<int>(j_sample);
+
+  g_histograms.Get()
+      .CountHistogram(env, j_histogram_name, j_histogram_key)
+      ->Add(sample);
+}
+
 void RecordCustomTimesHistogramMilliseconds(JNIEnv* env,
                                             jclass clazz,
                                             jstring j_histogram_name,
diff --git a/base.gyp b/base.gyp
index 5f640d8..c7a2481 100644
--- a/base.gyp
+++ b/base.gyp
@@ -541,7 +541,6 @@
         'mac/scoped_sending_event_unittest.mm',
         'md5_unittest.cc',
         'memory/aligned_memory_unittest.cc',
-        'memory/discardable_memory_unittest.cc',
         'memory/discardable_shared_memory_unittest.cc',
         'memory/linked_ptr_unittest.cc',
         'memory/ref_counted_memory_unittest.cc',
@@ -976,6 +975,8 @@
         'test/simple_test_tick_clock.h',
         'test/task_runner_test_template.cc',
         'test/task_runner_test_template.h',
+        'test/test_discardable_memory_shmem_allocator.cc',
+        'test/test_discardable_memory_shmem_allocator.h',
         'test/test_file_util.cc',
         'test/test_file_util.h',
         'test/test_file_util_android.cc',
diff --git a/base.gypi b/base.gypi
index ebc7e3e..13cba85 100644
--- a/base.gypi
+++ b/base.gypi
@@ -318,14 +318,10 @@
           'memory/aligned_memory.h',
           'memory/discardable_memory.cc',
           'memory/discardable_memory.h',
-          'memory/discardable_memory_android.cc',
-          'memory/discardable_memory_linux.cc',
-          'memory/discardable_memory_mac.cc',
           'memory/discardable_memory_shmem.cc',
           'memory/discardable_memory_shmem.h',
           'memory/discardable_memory_shmem_allocator.cc',
           'memory/discardable_memory_shmem_allocator.h',
-          'memory/discardable_memory_win.cc',
           'memory/discardable_shared_memory.cc',
           'memory/discardable_shared_memory.h',
           'memory/linked_ptr.h',
@@ -889,7 +885,6 @@
               ['include', '^mac/scoped_mach_vm\\.'],
               ['include', '^mac/scoped_nsautorelease_pool\\.'],
               ['include', '^mac/scoped_nsobject\\.'],
-              ['include', '^memory/discardable_memory_mac\\.'],
               ['include', '^message_loop/message_pump_mac\\.'],
               ['include', '^strings/sys_string_conversions_mac\\.'],
               ['include', '^threading/platform_thread_mac\\.'],
diff --git a/base_paths_win.cc b/base_paths_win.cc
index 5bef310..4ecb59d 100644
--- a/base_paths_win.cc
+++ b/base_paths_win.cc
@@ -6,8 +6,10 @@
 #include <shlobj.h>
 
 #include "base/base_paths.h"
+#include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_co_mem.h"
 #include "base/win/windows_version.h"
 
@@ -65,6 +67,27 @@
         return false;
       cur = FilePath(system_buffer);
       break;
+    case base::DIR_PROGRAM_FILES6432:
+#if !defined(_WIN64)
+      if (base::win::OSInfo::GetInstance()->wow64_status() ==
+          base::win::OSInfo::WOW64_ENABLED) {
+        scoped_ptr<base::Environment> env(base::Environment::Create());
+        std::string programfiles_w6432;
+        // 32-bit process running in WOW64 sets ProgramW6432 environment
+        // variable. See
+        // https://msdn.microsoft.com/library/windows/desktop/aa384274.aspx.
+        if (!env->GetVar("ProgramW6432", &programfiles_w6432))
+          return false;
+        // GetVar returns UTF8 - convert back to Wide.
+        cur = FilePath(UTF8ToWide(programfiles_w6432));
+        break;
+      }
+#endif
+      if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
+                                 SHGFP_TYPE_CURRENT, system_buffer)))
+        return false;
+      cur = FilePath(system_buffer);
+      break;
     case base::DIR_IE_INTERNET_CACHE:
       if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
                                  SHGFP_TYPE_CURRENT, system_buffer)))
diff --git a/base_paths_win.h b/base_paths_win.h
index 032de34..4ab6af1 100644
--- a/base_paths_win.h
+++ b/base_paths_win.h
@@ -16,8 +16,14 @@
 
   DIR_WINDOWS,  // Windows directory, usually "c:\windows"
   DIR_SYSTEM,   // Usually c:\windows\system32"
-  DIR_PROGRAM_FILES,      // Usually c:\program files
-  DIR_PROGRAM_FILESX86,   // Usually c:\program files or c:\program files (x86)
+  //                         32-bit     32-bit on 64-bit   64-bit on 64-bit
+  // DIR_PROGRAM_FILES         1               2                  1
+  // DIR_PROGRAM_FILESX86      1               2                  2
+  // DIR_PROGRAM_FILES6432     1               1                  1
+  // 1 - C:\Program Files   2 - C:\Program Files (x86)
+  DIR_PROGRAM_FILES,      // See table above.
+  DIR_PROGRAM_FILESX86,   // See table above.
+  DIR_PROGRAM_FILES6432,  // See table above.
 
   DIR_IE_INTERNET_CACHE,  // Temporary Internet Files directory.
   DIR_COMMON_START_MENU,  // Usually "C:\Documents and Settings\All Users\
diff --git a/compiler_specific.h b/compiler_specific.h
index 47ca977..034cf06 100644
--- a/compiler_specific.h
+++ b/compiler_specific.h
@@ -175,9 +175,17 @@
 // Mark a memory region fully initialized.
 // Use this to annotate code that deliberately reads uninitialized data, for
 // example a GC scavenging root set pointers from the stack.
-#define MSAN_UNPOISON(p, s)  __msan_unpoison(p, s)
+#define MSAN_UNPOISON(p, size)  __msan_unpoison(p, size)
+
+// Check a memory region for initializedness, as if it was being used here.
+// If any bits are uninitialized, crash with an MSan report.
+// Use this to sanitize data which MSan won't be able to track, e.g. before
+// passing data to another process via shared memory.
+#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
+    __msan_check_mem_is_initialized(p, size)
 #else  // MEMORY_SANITIZER
-#define MSAN_UNPOISON(p, s)
+#define MSAN_UNPOISON(p, size)
+#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
 #endif  // MEMORY_SANITIZER
 
 // Macro useful for writing cross-platform function pointers.
diff --git a/debug/BUILD.gn b/debug/BUILD.gn
index 37a0ab2..8ed623b 100644
--- a/debug/BUILD.gn
+++ b/debug/BUILD.gn
@@ -55,7 +55,7 @@
     ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   deps = [
     "//base/memory",
@@ -63,6 +63,7 @@
   ]
 
   if (is_linux) {
+    defines = [ "USE_SYMBOLIZE" ]
     deps += [ "//base/third_party/symbolize" ]
   }
 
diff --git a/files/file_posix.cc b/files/file_posix.cc
index 245ea6a..663f099 100644
--- a/files/file_posix.cc
+++ b/files/file_posix.cc
@@ -471,12 +471,15 @@
     case EROFS:
     case EPERM:
       return FILE_ERROR_ACCESS_DENIED;
+    case EBUSY:
 #if !defined(OS_NACL)  // ETXTBSY not defined by NaCl.
     case ETXTBSY:
-      return FILE_ERROR_IN_USE;
 #endif
+      return FILE_ERROR_IN_USE;
     case EEXIST:
       return FILE_ERROR_EXISTS;
+    case EIO:
+      return FILE_ERROR_IO;
     case ENOENT:
       return FILE_ERROR_NOT_FOUND;
     case EMFILE:
diff --git a/ios/weak_nsobject.h b/ios/weak_nsobject.h
index a1984bb..fc3a7c3 100644
--- a/ios/weak_nsobject.h
+++ b/ios/weak_nsobject.h
@@ -117,7 +117,9 @@
   }
 
   WeakNSProtocol& operator=(const WeakNSProtocol<NST>& that) {
-    DCHECK(checker_.CalledOnValidThread());
+    // A WeakNSProtocol object can be copied on one thread and used on
+    // another.
+    checker_.DetachFromThread();
     container_ = that.container_;
     return *this;
   }
diff --git a/ios/weak_nsobject_unittest.mm b/ios/weak_nsobject_unittest.mm
index 325dcd2..81de993 100644
--- a/ios/weak_nsobject_unittest.mm
+++ b/ios/weak_nsobject_unittest.mm
@@ -109,8 +109,12 @@
 // the weak object on its original thread.
 void CopyWeakNSObjectAndPost(const WeakNSObject<NSMutableData>& weak_object,
                              scoped_refptr<SingleThreadTaskRunner> runner) {
-  WeakNSObject<NSMutableData> weak_copy(weak_object);
-  runner->PostTask(FROM_HERE, Bind(&TouchWeakData, weak_copy));
+  // Copy using constructor.
+  WeakNSObject<NSMutableData> weak_copy1(weak_object);
+  runner->PostTask(FROM_HERE, Bind(&TouchWeakData, weak_copy1));
+  // Copy using assignment operator.
+  WeakNSObject<NSMutableData> weak_copy2 = weak_object;
+  runner->PostTask(FROM_HERE, Bind(&TouchWeakData, weak_copy2));
 }
 
 // Tests that the weak object can be copied on a different thread.
@@ -128,8 +132,8 @@
   other_thread.Stop();
   loop.RunUntilIdle();
 
-  // Check that TouchWeakData was called.
-  EXPECT_EQ(1u, [data length]);
+  // Check that TouchWeakData was called and the object touched twice.
+  EXPECT_EQ(2u, [data length]);
 }
 
 }  // namespace
diff --git a/json/BUILD.gn b/json/BUILD.gn
index 0310ea9..70830c1 100644
--- a/json/BUILD.gn
+++ b/json/BUILD.gn
@@ -27,7 +27,7 @@
     ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   deps = [
     "//base/memory",
diff --git a/location.cc b/location.cc
index 8b32b97..1333e6e 100644
--- a/location.cc
+++ b/location.cc
@@ -31,6 +31,13 @@
       program_counter_(NULL) {
 }
 
+Location::Location(const Location& other)
+    : function_name_(other.function_name_),
+      file_name_(other.file_name_),
+      line_number_(other.line_number_),
+      program_counter_(other.program_counter_) {
+}
+
 std::string Location::ToString() const {
   return std::string(function_name_) + "@" + file_name_ + ":" +
       base::IntToString(line_number_);
diff --git a/location.h b/location.h
index 05a4f66..477dc02 100644
--- a/location.h
+++ b/location.h
@@ -5,10 +5,12 @@
 #ifndef BASE_LOCATION_H_
 #define BASE_LOCATION_H_
 
+#include <cassert>
 #include <string>
 
 #include "base/base_export.h"
 #include "base/basictypes.h"
+#include "base/containers/hash_tables.h"
 
 namespace tracked_objects {
 
@@ -27,18 +29,15 @@
   // Provide a default constructor for easy of debugging.
   Location();
 
-  // Comparison operator for insertion into a std::map<> hash tables.
-  // All we need is *some* (any) hashing distinction.  Strings should already
-  // be unique, so we don't bother with strcmp or such.
-  // Use line number as the primary key (because it is fast, and usually gets us
-  // a difference), and then pointers as secondary keys (just to get some
-  // distinctions).
-  bool operator < (const Location& other) const {
-    if (line_number_ != other.line_number_)
-      return line_number_ < other.line_number_;
-    if (file_name_ != other.file_name_)
-      return file_name_ < other.file_name_;
-    return function_name_ < other.function_name_;
+  // Copy constructor.
+  Location(const Location& other);
+
+  // Comparator for hash map insertion.
+  // No need to use |function_name_| since the other two fields uniquely
+  // identify this location.
+  bool operator==(const Location& other) const {
+    return line_number_ == other.line_number_ &&
+           file_name_ == other.file_name_;
   }
 
   const char* function_name()   const { return function_name_; }
@@ -48,6 +47,26 @@
 
   std::string ToString() const;
 
+  // Hash operator for hash maps.
+  struct Hash {
+    size_t operator()(const Location& location) const {
+      // Compute the hash value using file name pointer and line number.
+      // No need to use |function_name_| since the other two fields uniquely
+      // identify this location.
+
+      // The file name will always be uniquely identified by its pointer since
+      // it comes from __FILE__, so no need to check the contents of the string.
+      // See the definition of FROM_HERE in location.h, and how it is used
+      // elsewhere.
+
+      // Due to inconsistent definitions of uint64_t and uintptr_t, casting the
+      // file name pointer to a uintptr_t causes a compiler error for some
+      // platforms. The solution is to explicitly cast it to a uint64_t.
+      return base::HashPair(reinterpret_cast<uint64_t>(location.file_name()),
+                            location.line_number());
+    }
+  };
+
   // Translate the some of the state in this instance into a human readable
   // string with HTML characters in the function names escaped, and append that
   // string to |output|.  Inclusion of the file_name_ and function_name_ are
diff --git a/mac/scoped_mach_port.h b/mac/scoped_mach_port.h
index 9ef90d6..beb62b0 100644
--- a/mac/scoped_mach_port.h
+++ b/mac/scoped_mach_port.h
@@ -20,7 +20,7 @@
     return MACH_PORT_NULL;
   }
 
-  static void Free(mach_port_t port);
+  BASE_EXPORT static void Free(mach_port_t port);
 };
 
 struct BASE_EXPORT ReceiveRightTraits {
@@ -28,7 +28,7 @@
     return MACH_PORT_NULL;
   }
 
-  static void Free(mach_port_t port);
+  BASE_EXPORT static void Free(mach_port_t port);
 };
 
 struct PortSetTraits {
@@ -36,7 +36,7 @@
     return MACH_PORT_NULL;
   }
 
-  static void Free(mach_port_t port);
+  BASE_EXPORT static void Free(mach_port_t port);
 };
 
 }  // namespace internal
diff --git a/memory/BUILD.gn b/memory/BUILD.gn
index 5d016ff..3d4c22c 100644
--- a/memory/BUILD.gn
+++ b/memory/BUILD.gn
@@ -8,14 +8,10 @@
     "aligned_memory.h",
     "discardable_memory.cc",
     "discardable_memory.h",
-    "discardable_memory_android.cc",
-    "discardable_memory_linux.cc",
-    "discardable_memory_mac.cc",
     "discardable_memory_shmem.cc",
     "discardable_memory_shmem.h",
     "discardable_memory_shmem_allocator.cc",
     "discardable_memory_shmem_allocator.h",
-    "discardable_memory_win.cc",
     "discardable_shared_memory.cc",
     "discardable_shared_memory.h",
     "linked_ptr.h",
@@ -58,7 +54,7 @@
     sources -= [ "shared_memory_nacl.cc" ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   visibility = [ "//base/*" ]
 }
diff --git a/memory/discardable_memory.cc b/memory/discardable_memory.cc
index 7d19f9a..0e3b58a 100644
--- a/memory/discardable_memory.cc
+++ b/memory/discardable_memory.cc
@@ -4,80 +4,14 @@
 
 #include "base/memory/discardable_memory.h"
 
-#include "base/lazy_instance.h"
-#include "base/logging.h"
+#include "base/memory/discardable_memory_shmem.h"
 
 namespace base {
-namespace {
-
-const struct TypeNamePair {
-  DiscardableMemoryType type;
-  const char* name;
-} kTypeNamePairs[] = {
-  { DISCARDABLE_MEMORY_TYPE_SHMEM, "shmem" }
-};
-
-DiscardableMemoryType g_preferred_type = DISCARDABLE_MEMORY_TYPE_NONE;
-
-struct DefaultPreferredType {
-  DefaultPreferredType() : value(DISCARDABLE_MEMORY_TYPE_NONE) {
-    std::vector<DiscardableMemoryType> supported_types;
-    DiscardableMemory::GetSupportedTypes(&supported_types);
-    DCHECK(!supported_types.empty());
-    value = supported_types[0];
-  }
-  DiscardableMemoryType value;
-};
-LazyInstance<DefaultPreferredType>::Leaky g_default_preferred_type =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-// static
-DiscardableMemoryType DiscardableMemory::GetNamedType(
-    const std::string& name) {
-  for (size_t i = 0; i < arraysize(kTypeNamePairs); ++i) {
-    if (name == kTypeNamePairs[i].name)
-      return kTypeNamePairs[i].type;
-  }
-
-  return DISCARDABLE_MEMORY_TYPE_NONE;
-}
-
-// static
-const char* DiscardableMemory::GetTypeName(DiscardableMemoryType type) {
-  for (size_t i = 0; i < arraysize(kTypeNamePairs); ++i) {
-    if (type == kTypeNamePairs[i].type)
-      return kTypeNamePairs[i].name;
-  }
-
-  return "unknown";
-}
-
-// static
-void DiscardableMemory::SetPreferredType(DiscardableMemoryType type) {
-  // NONE is a reserved value and not a valid default type.
-  DCHECK_NE(DISCARDABLE_MEMORY_TYPE_NONE, type);
-
-  // Make sure this function is only called once before the first call
-  // to GetPreferredType().
-  DCHECK_EQ(DISCARDABLE_MEMORY_TYPE_NONE, g_preferred_type);
-
-  g_preferred_type = type;
-}
-
-// static
-DiscardableMemoryType DiscardableMemory::GetPreferredType() {
-  if (g_preferred_type == DISCARDABLE_MEMORY_TYPE_NONE)
-    g_preferred_type = g_default_preferred_type.Get().value;
-
-  return g_preferred_type;
-}
 
 // static
 scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemory(
     size_t size) {
-  return CreateLockedMemoryWithType(GetPreferredType(), size);
+  return make_scoped_ptr(new internal::DiscardableMemoryShmem(size));
 }
 
 }  // namespace base
diff --git a/memory/discardable_memory.h b/memory/discardable_memory.h
index 4e5a9af..ce0f0bb 100644
--- a/memory/discardable_memory.h
+++ b/memory/discardable_memory.h
@@ -15,11 +15,6 @@
 
 namespace base {
 
-enum DiscardableMemoryType {
-  DISCARDABLE_MEMORY_TYPE_NONE,
-  DISCARDABLE_MEMORY_TYPE_SHMEM
-};
-
 // Platform abstraction for discardable memory. DiscardableMemory is used to
 // cache large objects without worrying about blowing out memory, both on mobile
 // devices where there is no swap, and desktop devices where unused free memory
@@ -55,29 +50,7 @@
  public:
   virtual ~DiscardableMemory() {}
 
-  // Gets the discardable memory type with a given name.
-  static DiscardableMemoryType GetNamedType(const std::string& name);
-
-  // Gets the name of a discardable memory type.
-  static const char* GetTypeName(DiscardableMemoryType type);
-
-  // Gets system supported discardable memory types. Default preferred type
-  // at the front of vector.
-  static void GetSupportedTypes(std::vector<DiscardableMemoryType>* types);
-
-  // Sets the preferred discardable memory type. This overrides the default
-  // preferred type. Can only be called once prior to GetPreferredType()
-  // or CreateLockedMemory(). Caller is responsible for correct ordering.
-  static void SetPreferredType(DiscardableMemoryType type);
-
-  // Gets the preferred discardable memory type.
-  static DiscardableMemoryType GetPreferredType();
-
-  // Create a DiscardableMemory instance with specified |type| and |size|.
-  static scoped_ptr<DiscardableMemory> CreateLockedMemoryWithType(
-      DiscardableMemoryType type, size_t size);
-
-  // Create a DiscardableMemory instance with preferred type and |size|.
+  // Create a DiscardableMemory instance with |size|.
   static scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size);
 
   // Locks the memory so that it will not be purged by the system. Returns
diff --git a/memory/discardable_memory_android.cc b/memory/discardable_memory_android.cc
deleted file mode 100644
index a36f54e..0000000
--- a/memory/discardable_memory_android.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2013 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/memory/discardable_memory.h"
-
-#include "base/logging.h"
-#include "base/memory/discardable_memory_shmem.h"
-
-namespace base {
-
-// static
-void DiscardableMemory::GetSupportedTypes(
-    std::vector<DiscardableMemoryType>* types) {
-  const DiscardableMemoryType supported_types[] = {
-    DISCARDABLE_MEMORY_TYPE_SHMEM
-  };
-  types->assign(supported_types, supported_types + arraysize(supported_types));
-}
-
-// static
-scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType(
-    DiscardableMemoryType type, size_t size) {
-  switch (type) {
-    case DISCARDABLE_MEMORY_TYPE_SHMEM:
-      return make_scoped_ptr(new internal::DiscardableMemoryShmem(size));
-    case DISCARDABLE_MEMORY_TYPE_NONE:
-      NOTREACHED();
-      return nullptr;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace base
diff --git a/memory/discardable_memory_linux.cc b/memory/discardable_memory_linux.cc
deleted file mode 100644
index b394e07..0000000
--- a/memory/discardable_memory_linux.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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/memory/discardable_memory.h"
-
-#include "base/logging.h"
-#include "base/memory/discardable_memory_shmem.h"
-
-namespace base {
-
-// static
-void DiscardableMemory::GetSupportedTypes(
-    std::vector<DiscardableMemoryType>* types) {
-  const DiscardableMemoryType supported_types[] = {
-    DISCARDABLE_MEMORY_TYPE_SHMEM
-  };
-  types->assign(supported_types, supported_types + arraysize(supported_types));
-}
-
-// static
-scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType(
-    DiscardableMemoryType type, size_t size) {
-  switch (type) {
-    case DISCARDABLE_MEMORY_TYPE_SHMEM:
-      return make_scoped_ptr(new internal::DiscardableMemoryShmem(size));
-    case DISCARDABLE_MEMORY_TYPE_NONE:
-      NOTREACHED();
-      return nullptr;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace base
diff --git a/memory/discardable_memory_mac.cc b/memory/discardable_memory_mac.cc
deleted file mode 100644
index d7e6345..0000000
--- a/memory/discardable_memory_mac.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2013 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/memory/discardable_memory.h"
-
-#include "base/logging.h"
-#include "base/memory/discardable_memory_shmem.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace base {
-
-// static
-void DiscardableMemory::GetSupportedTypes(
-    std::vector<DiscardableMemoryType>* types) {
-  const DiscardableMemoryType supported_types[] = {
-    DISCARDABLE_MEMORY_TYPE_SHMEM
-  };
-  types->assign(supported_types, supported_types + arraysize(supported_types));
-}
-
-// static
-scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType(
-    DiscardableMemoryType type, size_t size) {
-  switch (type) {
-    case DISCARDABLE_MEMORY_TYPE_SHMEM:
-      return make_scoped_ptr(new internal::DiscardableMemoryShmem(size));
-    case DISCARDABLE_MEMORY_TYPE_NONE:
-      NOTREACHED();
-      return nullptr;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace base
diff --git a/memory/discardable_memory_shmem_allocator.cc b/memory/discardable_memory_shmem_allocator.cc
index 761204f..a87c58d 100644
--- a/memory/discardable_memory_shmem_allocator.cc
+++ b/memory/discardable_memory_shmem_allocator.cc
@@ -11,45 +11,6 @@
 namespace base {
 namespace {
 
-class DiscardableMemoryShmemChunkImpl : public DiscardableMemoryShmemChunk {
- public:
-  explicit DiscardableMemoryShmemChunkImpl(
-      scoped_ptr<DiscardableSharedMemory> shared_memory)
-      : shared_memory_(shared_memory.Pass()) {}
-
-  // Overridden from DiscardableMemoryShmemChunk:
-  bool Lock() override { return false; }
-  void Unlock() override {
-    shared_memory_->Unlock(0, 0);
-    shared_memory_.reset();
-  }
-  void* Memory() const override { return shared_memory_->memory(); }
-
- private:
-  scoped_ptr<DiscardableSharedMemory> shared_memory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryShmemChunkImpl);
-};
-
-// Default allocator implementation that allocates in-process
-// DiscardableSharedMemory instances.
-class DiscardableMemoryShmemAllocatorImpl
-    : public DiscardableMemoryShmemAllocator {
- public:
-  // Overridden from DiscardableMemoryShmemAllocator:
-  scoped_ptr<DiscardableMemoryShmemChunk>
-  AllocateLockedDiscardableMemory(size_t size) override {
-    scoped_ptr<DiscardableSharedMemory> memory(new DiscardableSharedMemory);
-    if (!memory->CreateAndMap(size))
-      return nullptr;
-
-    return make_scoped_ptr(new DiscardableMemoryShmemChunkImpl(memory.Pass()));
-  }
-};
-
-LazyInstance<DiscardableMemoryShmemAllocatorImpl>::Leaky g_default_allocator =
-    LAZY_INSTANCE_INITIALIZER;
-
 DiscardableMemoryShmemAllocator* g_allocator = nullptr;
 
 }  // namespace
@@ -69,9 +30,7 @@
 // static
 DiscardableMemoryShmemAllocator*
 DiscardableMemoryShmemAllocator::GetInstance() {
-  if (!g_allocator)
-    g_allocator = g_default_allocator.Pointer();
-
+  DCHECK(g_allocator);
   return g_allocator;
 }
 
diff --git a/memory/discardable_memory_unittest.cc b/memory/discardable_memory_unittest.cc
deleted file mode 100644
index a769e17..0000000
--- a/memory/discardable_memory_unittest.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2013 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/memory/discardable_memory.h"
-
-#include <algorithm>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(OS_ANDROID)
-#include <limits>
-#endif
-
-namespace base {
-namespace {
-
-class DiscardableMemoryTest
-    : public testing::TestWithParam<DiscardableMemoryType> {
- public:
-  DiscardableMemoryTest() {}
-  virtual ~DiscardableMemoryTest() {
-  }
-
- protected:
-  scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) {
-    return DiscardableMemory::CreateLockedMemoryWithType(
-        GetParam(), size).Pass();
-  }
-};
-
-const size_t kSize = 1024;
-
-TEST_P(DiscardableMemoryTest, IsNamed) {
-  std::string type_name(DiscardableMemory::GetTypeName(GetParam()));
-  EXPECT_NE("unknown", type_name);
-  EXPECT_EQ(GetParam(), DiscardableMemory::GetNamedType(type_name));
-}
-
-bool IsNativeType(DiscardableMemoryType type) {
-#if defined(OS_ANDROID)
-    // SHMEM is backed by native discardable memory on Android.
-  return type == DISCARDABLE_MEMORY_TYPE_SHMEM;
-#else
-  return false;
-#endif
-}
-
-TEST_P(DiscardableMemoryTest, SupportedNatively) {
-  std::vector<DiscardableMemoryType> supported_types;
-  DiscardableMemory::GetSupportedTypes(&supported_types);
-#if defined(DISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY)
-  EXPECT_NE(0, std::count_if(supported_types.begin(),
-                             supported_types.end(),
-                             IsNativeType));
-#else
-  // If we ever have a platform that decides at runtime if it can support
-  // discardable memory natively, then we'll have to add a 'never supported
-  // natively' define for this case. At present, if it's not always supported
-  // natively, it's never supported.
-  EXPECT_EQ(0, std::count_if(supported_types.begin(),
-                             supported_types.end(),
-                             IsNativeType));
-#endif
-}
-
-// Test Lock() and Unlock() functionalities.
-TEST_P(DiscardableMemoryTest, LockAndUnLock) {
-  const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
-  ASSERT_TRUE(memory);
-  void* addr = memory->Memory();
-  EXPECT_NE(nullptr, addr);
-  memory->Unlock();
-}
-
-// Test delete a discardable memory while it is locked.
-TEST_P(DiscardableMemoryTest, DeleteWhileLocked) {
-  const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
-  ASSERT_TRUE(memory);
-}
-
-#if !defined(NDEBUG) && !defined(OS_ANDROID)
-// Death tests are not supported with Android APKs.
-TEST_P(DiscardableMemoryTest, UnlockedMemoryAccessCrashesInDebugMode) {
-  const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
-  ASSERT_TRUE(memory);
-  memory->Unlock();
-  ASSERT_DEATH_IF_SUPPORTED(
-      { *static_cast<int*>(memory->Memory()) = 0xdeadbeef; }, ".*");
-}
-#endif
-
-// Test behavior when creating enough instances that could use up a 32-bit
-// address space.
-// This is disabled under AddressSanitizer on Windows as it crashes (by design)
-// on OOM. See http://llvm.org/PR22026 for the details.
-#if !defined(ADDRESS_SANITIZER) || !defined(OS_WIN)
-TEST_P(DiscardableMemoryTest, AddressSpace) {
-  const size_t kLargeSize = 4 * 1024 * 1024;  // 4MiB.
-  const size_t kNumberOfInstances = 1024 + 1;  // >4GiB total.
-
-  scoped_ptr<DiscardableMemory> instances[kNumberOfInstances];
-  for (auto& memory : instances) {
-    memory = CreateLockedMemory(kLargeSize);
-    ASSERT_TRUE(memory);
-    void* addr = memory->Memory();
-    EXPECT_NE(nullptr, addr);
-    memory->Unlock();
-  }
-}
-#endif
-
-std::vector<DiscardableMemoryType> GetSupportedDiscardableMemoryTypes() {
-  std::vector<DiscardableMemoryType> supported_types;
-  DiscardableMemory::GetSupportedTypes(&supported_types);
-  return supported_types;
-}
-
-INSTANTIATE_TEST_CASE_P(
-    DiscardableMemoryTests,
-    DiscardableMemoryTest,
-    ::testing::ValuesIn(GetSupportedDiscardableMemoryTypes()));
-
-}  // namespace
-}  // namespace base
diff --git a/memory/discardable_memory_win.cc b/memory/discardable_memory_win.cc
deleted file mode 100644
index b394e07..0000000
--- a/memory/discardable_memory_win.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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/memory/discardable_memory.h"
-
-#include "base/logging.h"
-#include "base/memory/discardable_memory_shmem.h"
-
-namespace base {
-
-// static
-void DiscardableMemory::GetSupportedTypes(
-    std::vector<DiscardableMemoryType>* types) {
-  const DiscardableMemoryType supported_types[] = {
-    DISCARDABLE_MEMORY_TYPE_SHMEM
-  };
-  types->assign(supported_types, supported_types + arraysize(supported_types));
-}
-
-// static
-scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType(
-    DiscardableMemoryType type, size_t size) {
-  switch (type) {
-    case DISCARDABLE_MEMORY_TYPE_SHMEM:
-      return make_scoped_ptr(new internal::DiscardableMemoryShmem(size));
-    case DISCARDABLE_MEMORY_TYPE_NONE:
-      NOTREACHED();
-      return nullptr;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace base
diff --git a/metrics/BUILD.gn b/metrics/BUILD.gn
index 804e59b..0202637 100644
--- a/metrics/BUILD.gn
+++ b/metrics/BUILD.gn
@@ -37,7 +37,7 @@
     sources -= [ "field_trial.cc" ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   deps = [
     "//base/debug",
diff --git a/path_service_unittest.cc b/path_service_unittest.cc
index 543deb6..7551d67 100644
--- a/path_service_unittest.cc
+++ b/path_service_unittest.cc
@@ -220,3 +220,55 @@
   EXPECT_TRUE(PathService::Get(base::DIR_TEMP, &new_user_data_dir));
   EXPECT_EQ(original_user_data_dir, new_user_data_dir);
 }
+
+#if defined(OS_WIN)
+TEST_F(PathServiceTest, GetProgramFiles) {
+  base::FilePath programfiles_dir;
+#if defined(_WIN64)
+  // 64-bit on 64-bit.
+  EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES,
+      &programfiles_dir));
+  EXPECT_EQ(programfiles_dir.value(),
+      FILE_PATH_LITERAL("C:\\Program Files"));
+  EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILESX86,
+      &programfiles_dir));
+  EXPECT_EQ(programfiles_dir.value(),
+      FILE_PATH_LITERAL("C:\\Program Files (x86)"));
+  EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES6432,
+      &programfiles_dir));
+  EXPECT_EQ(programfiles_dir.value(),
+      FILE_PATH_LITERAL("C:\\Program Files"));
+#else
+  if (base::win::OSInfo::GetInstance()->wow64_status() ==
+      base::win::OSInfo::WOW64_ENABLED) {
+    // 32-bit on 64-bit.
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files (x86)"));
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILESX86,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files (x86)"));
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES6432,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files"));
+  } else {
+    // 32-bit on 32-bit.
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files"));
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILESX86,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files"));
+    EXPECT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES6432,
+        &programfiles_dir));
+    EXPECT_EQ(programfiles_dir.value(),
+        FILE_PATH_LITERAL("C:\\Program Files"));
+  }
+#endif
+}
+#endif
diff --git a/pickle.cc b/pickle.cc
index 6eb207f..112ddc3 100644
--- a/pickle.cc
+++ b/pickle.cc
@@ -358,6 +358,7 @@
 inline void Pickle::WriteBytesCommon(const void* data, size_t length) {
   DCHECK_NE(kCapacityReadOnly, capacity_after_header_)
       << "oops: pickle is readonly";
+  MSAN_CHECK_MEM_IS_INITIALIZED(data, length);
   size_t data_len = AlignInt(length, sizeof(uint32));
   DCHECK_GE(data_len, length);
 #ifdef ARCH_CPU_64_BITS
diff --git a/process/BUILD.gn b/process/BUILD.gn
index 125b451..e570647 100644
--- a/process/BUILD.gn
+++ b/process/BUILD.gn
@@ -94,7 +94,7 @@
     ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   deps = [
     "//base/memory",
diff --git a/process/launch.cc b/process/launch.cc
index 1c752bd..c179b2f 100644
--- a/process/launch.cc
+++ b/process/launch.cc
@@ -27,6 +27,7 @@
 #if defined(OS_LINUX)
       , clone_flags(0)
       , allow_new_privs(false)
+      , kill_on_parent_death(false)
 #endif  // OS_LINUX
 #if defined(OS_POSIX)
       , pre_exec_delegate(NULL)
diff --git a/process/launch.h b/process/launch.h
index 775e65c..56f27a8 100644
--- a/process/launch.h
+++ b/process/launch.h
@@ -141,6 +141,9 @@
   // By default, child processes will have the PR_SET_NO_NEW_PRIVS bit set. If
   // true, then this bit will not be set in the new child process.
   bool allow_new_privs;
+
+  // Sets parent process death signal to SIGKILL.
+  bool kill_on_parent_death;
 #endif  // defined(OS_LINUX)
 
 #if defined(OS_POSIX)
diff --git a/process/launch_posix.cc b/process/launch_posix.cc
index f9963fa..77edc12 100644
--- a/process/launch_posix.cc
+++ b/process/launch_posix.cc
@@ -523,6 +523,13 @@
         RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed");
       }
     }
+
+    if (options.kill_on_parent_death) {
+      if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0) {
+        RAW_LOG(ERROR, "prctl(PR_SET_PDEATHSIG) failed");
+        _exit(127);
+      }
+    }
 #endif
 
     if (current_directory != nullptr) {
diff --git a/process/process.h b/process/process.h
index 41eef10..045f870 100644
--- a/process/process.h
+++ b/process/process.h
@@ -55,7 +55,7 @@
   // Returns a Process for the given |pid|. On Windows the handle is opened
   // with more access rights and must only be used by trusted code (can read the
   // address space and duplicate handles).
-  static Process OpenWithExtraPriviles(ProcessId pid);
+  static Process OpenWithExtraPrivileges(ProcessId pid);
 
 #if defined(OS_WIN)
   // Returns a Process for the given |pid|, using some |desired_access|.
diff --git a/process/process_posix.cc b/process/process_posix.cc
index 1c4210b..a083123 100644
--- a/process/process_posix.cc
+++ b/process/process_posix.cc
@@ -238,7 +238,7 @@
 }
 
 // static
-Process Process::OpenWithExtraPriviles(ProcessId pid) {
+Process Process::OpenWithExtraPrivileges(ProcessId pid) {
   // On POSIX there are no privileges to set.
   return Open(pid);
 }
diff --git a/process/process_win.cc b/process/process_win.cc
index 32da8ab..d72dd49 100644
--- a/process/process_win.cc
+++ b/process/process_win.cc
@@ -54,7 +54,7 @@
 }
 
 // static
-Process Process::OpenWithExtraPriviles(ProcessId pid) {
+Process Process::OpenWithExtraPrivileges(ProcessId pid) {
   DWORD access = kBasicProcessAccess | PROCESS_DUP_HANDLE | PROCESS_VM_READ;
   return Process(::OpenProcess(access, FALSE, pid));
 }
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 55e710d..f5d2e4c 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -81,6 +81,8 @@
     "simple_test_tick_clock.h",
     "task_runner_test_template.cc",
     "task_runner_test_template.h",
+    "test_discardable_memory_shmem_allocator.cc",
+    "test_discardable_memory_shmem_allocator.h",
     "test_file_util.cc",
     "test_file_util.h",
     "test_file_util_android.cc",
diff --git a/test/launcher/test_launcher.cc b/test/launcher/test_launcher.cc
index 667d1eb..1d48060 100644
--- a/test/launcher/test_launcher.cc
+++ b/test/launcher/test_launcher.cc
@@ -383,6 +383,9 @@
   }
 #elif defined(OS_POSIX)
   options.new_process_group = true;
+#if defined(OS_LINUX)
+  options.kill_on_parent_death = true;
+#endif  // defined(OS_LINUX)
 
   FileHandleMappingVector fds_mapping;
   ScopedFD output_file_fd;
diff --git a/test/test_discardable_memory_shmem_allocator.cc b/test/test_discardable_memory_shmem_allocator.cc
new file mode 100644
index 0000000..24185a2
--- /dev/null
+++ b/test/test_discardable_memory_shmem_allocator.cc
@@ -0,0 +1,40 @@
+// 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/test/test_discardable_memory_shmem_allocator.h"
+
+#include <stdint.h>
+
+namespace base {
+namespace {
+
+class DiscardableMemoryShmemChunkImpl : public DiscardableMemoryShmemChunk {
+ public:
+  explicit DiscardableMemoryShmemChunkImpl(size_t size)
+      : memory_(new uint8_t[size]) {}
+
+  // Overridden from DiscardableMemoryShmemChunk:
+  bool Lock() override { return false; }
+  void Unlock() override {}
+  void* Memory() const override { return memory_.get(); }
+
+ private:
+  scoped_ptr<uint8_t[]> memory_;
+};
+
+}  // namespace
+
+TestDiscardableMemoryShmemAllocator::TestDiscardableMemoryShmemAllocator() {
+}
+
+TestDiscardableMemoryShmemAllocator::~TestDiscardableMemoryShmemAllocator() {
+}
+
+scoped_ptr<DiscardableMemoryShmemChunk>
+TestDiscardableMemoryShmemAllocator::AllocateLockedDiscardableMemory(
+    size_t size) {
+  return make_scoped_ptr(new DiscardableMemoryShmemChunkImpl(size));
+}
+
+}  // namespace base
diff --git a/test/test_discardable_memory_shmem_allocator.h b/test/test_discardable_memory_shmem_allocator.h
new file mode 100644
index 0000000..a40960e
--- /dev/null
+++ b/test/test_discardable_memory_shmem_allocator.h
@@ -0,0 +1,28 @@
+// 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_TEST_TEST_DISCARDABLE_MEMORY_SHMEM_ALLOCATOR_H_
+#define BASE_TEST_TEST_DISCARDABLE_MEMORY_SHMEM_ALLOCATOR_H_
+
+#include "base/memory/discardable_memory_shmem_allocator.h"
+
+namespace base {
+
+class TestDiscardableMemoryShmemAllocator
+    : public DiscardableMemoryShmemAllocator {
+ public:
+  TestDiscardableMemoryShmemAllocator();
+  ~TestDiscardableMemoryShmemAllocator() override;
+
+  // Overridden from DiscardableMemoryShmemAllocator:
+  scoped_ptr<DiscardableMemoryShmemChunk> AllocateLockedDiscardableMemory(
+      size_t size) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestDiscardableMemoryShmemAllocator);
+};
+
+}  // namespace base
+
+#endif  // BASE_TEST_TEST_DISCARDABLE_MEMORY_SHMEM_ALLOCATOR_H_
diff --git a/third_party/nspr/BUILD.gn b/third_party/nspr/BUILD.gn
index a67e168..034f37b 100644
--- a/third_party/nspr/BUILD.gn
+++ b/third_party/nspr/BUILD.gn
@@ -12,7 +12,7 @@
 
   # In GYP this project is part of base, so it uses the base implementation
   # define. TODO(brettw) rename this define.
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   if (is_android && !is_debug) {
     configs -= [ "//build/config/compiler:optimize" ]
diff --git a/threading/sequenced_worker_pool.cc b/threading/sequenced_worker_pool.cc
index f20d997..52b178b 100644
--- a/threading/sequenced_worker_pool.cc
+++ b/threading/sequenced_worker_pool.cc
@@ -803,6 +803,20 @@
           delete_these_outside_lock.clear();
           break;
         }
+
+        // No work was found, but there are tasks that need deletion. The
+        // deletion must happen outside of the lock.
+        if (delete_these_outside_lock.size()) {
+          AutoUnlock unlock(lock_);
+          delete_these_outside_lock.clear();
+
+          // Since the lock has been released, |status| may no longer be
+          // accurate. It might read GET_WORK_WAIT even if there are tasks
+          // ready to perform work. Jump to the top of the loop to recalculate
+          // |status|.
+          continue;
+        }
+
         waiting_thread_count_++;
 
         switch (status) {
diff --git a/threading/sequenced_worker_pool_unittest.cc b/threading/sequenced_worker_pool_unittest.cc
index c132731..5d0880c 100644
--- a/threading/sequenced_worker_pool_unittest.cc
+++ b/threading/sequenced_worker_pool_unittest.cc
@@ -148,6 +148,17 @@
         FROM_HERE, reposting_task, SequencedWorkerPool::SKIP_ON_SHUTDOWN);
   }
 
+  // This task reposts itself back onto the SequencedWorkerPool before it
+  // finishes running.
+  void PostRepostingBlockingTask(
+      const scoped_refptr<SequencedWorkerPool>& pool,
+      const SequencedWorkerPool::SequenceToken& token) {
+    Closure reposting_task =
+        base::Bind(&TestTracker::PostRepostingBlockingTask, this, pool, token);
+    pool->PostSequencedWorkerTaskWithShutdownBehavior(token,
+        FROM_HERE, reposting_task, SequencedWorkerPool::BLOCK_SHUTDOWN);
+  }
+
   // Waits until the given number of tasks have started executing.
   void WaitUntilTasksBlocked(size_t count) {
     {
@@ -795,6 +806,26 @@
   pool()->Shutdown();
 }
 
+// Similar to the test AvoidsDeadlockOnShutdown, but there are now also
+// sequenced, blocking tasks in the queue during shutdown.
+TEST_F(SequencedWorkerPoolTest,
+       AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) {
+  const std::string sequence_token_name("name");
+  for (int i = 0; i < 4; ++i) {
+    scoped_refptr<DestructionDeadlockChecker> checker(
+        new DestructionDeadlockChecker(pool()));
+    tracker()->PostRepostingTask(pool(), checker);
+
+    SequencedWorkerPool::SequenceToken token1 =
+        pool()->GetNamedSequenceToken(sequence_token_name);
+    tracker()->PostRepostingBlockingTask(pool(), token1);
+  }
+
+  // Shutting down the pool should destroy the DestructionDeadlockCheckers,
+  // which in turn should not deadlock in their destructors.
+  pool()->Shutdown();
+}
+
 // Verify that FlushForTesting works as intended.
 TEST_F(SequencedWorkerPoolTest, FlushForTesting) {
   // Should be fine to call on a new instance.
diff --git a/time/time.h b/time/time.h
index b18c0b2..6a45b81 100644
--- a/time/time.h
+++ b/time/time.h
@@ -233,13 +233,16 @@
 // Represents a wall clock time in UTC.
 class BASE_EXPORT Time {
  public:
+  static const int64 kHoursPerDay = 24;
   static const int64 kMillisecondsPerSecond = 1000;
+  static const int64 kMillisecondsPerDay = kMillisecondsPerSecond * 60 * 60 *
+                                           kHoursPerDay;
   static const int64 kMicrosecondsPerMillisecond = 1000;
   static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
                                               kMillisecondsPerSecond;
   static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
   static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
-  static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
+  static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * kHoursPerDay;
   static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
   static const int64 kNanosecondsPerMicrosecond = 1000;
   static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
diff --git a/trace_event/BUILD.gn b/trace_event/BUILD.gn
index eec607b..10f7ec9 100644
--- a/trace_event/BUILD.gn
+++ b/trace_event/BUILD.gn
@@ -41,7 +41,7 @@
     ]
   }
 
-  defines = [ "BASE_IMPLEMENTATION" ]
+  configs += [ "//base:base_implementation" ]
 
   deps = [
     "//base/debug",
diff --git a/trace_event/trace_event.h b/trace_event/trace_event.h
index b90a3ea..9d8e7d1 100644
--- a/trace_event/trace_event.h
+++ b/trace_event/trace_event.h
@@ -520,6 +520,27 @@
         value1_name, static_cast<int>(value1_val), \
         value2_name, static_cast<int>(value2_val))
 
+// TRACE_EVENT_SAMPLE_* events are injected by the sampling profiler.
+#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP0(category_group, name,       \
+                                                   thread_id, timestamp)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP1(                            \
+    category_group, name, thread_id, timestamp, arg1_name, arg1_val)           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+
+#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP2(category_group, name,       \
+                                                   thread_id, timestamp,       \
+                                                   arg1_name, arg1_val,        \
+                                                   arg2_name, arg2_val)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+
 // ASYNC_STEP_* APIs should be only used by legacy code. New code should
 // consider using NESTABLE_ASYNC_* APIs to describe substeps within an async
 // event.
diff --git a/tracked_objects.h b/tracked_objects.h
index 7840fec..34c3667 100644
--- a/tracked_objects.h
+++ b/tracked_objects.h
@@ -14,6 +14,7 @@
 
 #include "base/base_export.h"
 #include "base/basictypes.h"
+#include "base/containers/hash_tables.h"
 #include "base/gtest_prod_util.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
@@ -357,7 +358,7 @@
     STATUS_LAST = PROFILING_CHILDREN_ACTIVE
   };
 
-  typedef std::map<Location, Births*> BirthMap;
+  typedef base::hash_map<Location, Births*, Location::Hash> BirthMap;
   typedef std::map<const Births*, DeathData> DeathMap;
   typedef std::pair<const Births*, const Births*> ParentChildPair;
   typedef std::set<ParentChildPair> ParentChildSet;