Import Cobalt 22.master.0.303007

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5870
    by g.jiang@samsung.com
  https://cobalt-review.googlesource.com/c/cobalt/+/6078
    by zj.huang@samsung.corp-partner.google.com
  https://cobalt-review.googlesource.com/c/cobalt/+/6110
    by zj.huang@samsung.corp-partner.google.com
  https://cobalt-review.googlesource.com/c/cobalt/+/6085
    by xnicole.chen@samsung.com
  https://cobalt-review.googlesource.com/c/cobalt/+/6079
    by zj.huang@samsung.corp-partner.google.com
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 6fbe520..6900b8c 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -21,3 +21,13 @@
 
   deps = [ "//starboard:gn_all" ]
 }
+
+group("default") {
+  testonly = true
+
+  if (is_qa || is_gold) {
+    deps = [ "//starboard" ]
+  } else {
+    deps = [ ":gn_all" ]
+  }
+}
diff --git a/src/base/allocator/allocator_shim_default_dispatch_to_winheap.cc b/src/base/allocator/allocator_shim_default_dispatch_to_winheap.cc
index 71a73c7..8c93ae7 100644
--- a/src/base/allocator/allocator_shim_default_dispatch_to_winheap.cc
+++ b/src/base/allocator/allocator_shim_default_dispatch_to_winheap.cc
@@ -29,7 +29,7 @@
 
   void* result = DefaultWinHeapMallocImpl(self, size, context);
   if (result) {
-    SbMemorySet(result, 0, size);
+    memset(result, 0, size);
   }
   return result;
 }
diff --git a/src/base/allocator/allocator_shim_override_mac_symbols.h b/src/base/allocator/allocator_shim_override_mac_symbols.h
index fb009d8..aaa79ea 100644
--- a/src/base/allocator/allocator_shim_override_mac_symbols.h
+++ b/src/base/allocator/allocator_shim_override_mac_symbols.h
@@ -16,7 +16,7 @@
 
 MallocZoneFunctions MallocZoneFunctionsToReplaceDefault() {
   MallocZoneFunctions new_functions;
-  SbMemorySet(&new_functions, 0, sizeof(MallocZoneFunctions));
+  memset(&new_functions, 0, sizeof(MallocZoneFunctions));
   new_functions.size = [](malloc_zone_t* zone, const void* ptr) -> size_t {
     return ShimGetSizeEstimate(ptr, zone);
   };
diff --git a/src/base/allocator/allocator_shim_unittest.cc b/src/base/allocator/allocator_shim_unittest.cc
index f9ec2b0..8b82a0f 100644
--- a/src/base/allocator/allocator_shim_unittest.cc
+++ b/src/base/allocator/allocator_shim_unittest.cc
@@ -188,15 +188,15 @@
 
   void SetUp() override {
     const size_t array_size = kMaxSizeTracked * sizeof(size_t);
-    SbMemorySet(&allocs_intercepted_by_size, 0, array_size);
-    SbMemorySet(&zero_allocs_intercepted_by_size, 0, array_size);
-    SbMemorySet(&aligned_allocs_intercepted_by_size, 0, array_size);
-    SbMemorySet(&aligned_allocs_intercepted_by_alignment, 0, array_size);
-    SbMemorySet(&reallocs_intercepted_by_size, 0, array_size);
-    SbMemorySet(&frees_intercepted_by_addr, 0, array_size);
-    SbMemorySet(&batch_mallocs_intercepted_by_size, 0, array_size);
-    SbMemorySet(&batch_frees_intercepted_by_addr, 0, array_size);
-    SbMemorySet(&free_definite_sizes_intercepted_by_size, 0, array_size);
+    memset(&allocs_intercepted_by_size, 0, array_size);
+    memset(&zero_allocs_intercepted_by_size, 0, array_size);
+    memset(&aligned_allocs_intercepted_by_size, 0, array_size);
+    memset(&aligned_allocs_intercepted_by_alignment, 0, array_size);
+    memset(&reallocs_intercepted_by_size, 0, array_size);
+    memset(&frees_intercepted_by_addr, 0, array_size);
+    memset(&batch_mallocs_intercepted_by_size, 0, array_size);
+    memset(&batch_frees_intercepted_by_addr, 0, array_size);
+    memset(&free_definite_sizes_intercepted_by_size, 0, array_size);
     did_fail_realloc_0xfeed_once.reset(new ThreadLocalBoolean());
     subtle::Release_Store(&num_new_handler_calls, 0);
     instance_ = this;
@@ -315,7 +315,7 @@
 #endif  // !OS_WIN && !OS_MACOSX
 
   char* realloc_ptr = static_cast<char*>(SbMemoryAllocate(10));
-  SbStringCopyUnsafe(realloc_ptr, "foobar");
+  strcpy(realloc_ptr, "foobar");
   void* old_realloc_ptr = realloc_ptr;
   SbMemoryReallocate_ptr =
       static_cast<char*>(SbMemoryReallocate(SbMemoryReallocate_ptr, 73));
diff --git a/src/base/allocator/malloc_zone_functions_mac.cc b/src/base/allocator/malloc_zone_functions_mac.cc
index 83e8268..fb13091 100644
--- a/src/base/allocator/malloc_zone_functions_mac.cc
+++ b/src/base/allocator/malloc_zone_functions_mac.cc
@@ -17,7 +17,7 @@
 
 void StoreZoneFunctions(const ChromeMallocZone* zone,
                         MallocZoneFunctions* functions) {
-  SbMemorySet(functions, 0, sizeof(MallocZoneFunctions));
+  memset(functions, 0, sizeof(MallocZoneFunctions));
   functions->malloc = zone->malloc;
   functions->calloc = zone->calloc;
   functions->valloc = zone->valloc;
@@ -107,7 +107,7 @@
 void ClearAllMallocZonesForTesting() {
   base::AutoLock l(GetLock());
   EnsureMallocZonesInitializedLocked();
-  SbMemorySet(g_malloc_zones, 0, kMaxZoneCount * sizeof(MallocZoneFunctions));
+  memset(g_malloc_zones, 0, kMaxZoneCount * sizeof(MallocZoneFunctions));
   g_zone_count = 0;
 }
 
diff --git a/src/base/allocator/malloc_zone_functions_mac_unittest.cc b/src/base/allocator/malloc_zone_functions_mac_unittest.cc
index e387b80..8bb7348 100644
--- a/src/base/allocator/malloc_zone_functions_mac_unittest.cc
+++ b/src/base/allocator/malloc_zone_functions_mac_unittest.cc
@@ -46,7 +46,7 @@
   zones.resize(kMaxZoneCount * 2);
   for (int i = 0; i < kMaxZoneCount * 2; ++i) {
     ChromeMallocZone& zone = zones[i];
-    SbMemoryCopy(&zone, malloc_default_zone(), sizeof(ChromeMallocZone));
+    memcpy(&zone, malloc_default_zone(), sizeof(ChromeMallocZone));
     StoreMallocZone(&zone);
   }
 
diff --git a/src/base/allocator/partition_allocator/partition_alloc.cc b/src/base/allocator/partition_allocator/partition_alloc.cc
index 288aa92..c7343fc 100644
--- a/src/base/allocator/partition_allocator/partition_alloc.cc
+++ b/src/base/allocator/partition_allocator/partition_alloc.cc
@@ -235,7 +235,7 @@
     root->RecommitSystemPages(char_ptr + current_size, recommit_size);
 
 #if DCHECK_IS_ON()
-    SbMemorySet(char_ptr + current_size, kUninitializedByte, recommit_size);
+    memset(char_ptr + current_size, kUninitializedByte, recommit_size);
 #endif
   } else {
     // We can't perform the realloc in-place.
@@ -326,7 +326,7 @@
   if (new_size < copy_size)
     copy_size = new_size;
 
-  SbMemoryCopy(ret, ptr, copy_size);
+  memcpy(ret, ptr, copy_size);
   root->Free(ptr);
   return ret;
 #endif
@@ -378,7 +378,7 @@
   // DiscardVirtualMemory makes the contents of discarded memory undefined.
   size_t last_slot = static_cast<size_t>(-1);
 #endif
-  SbMemorySet(slot_usage, 1, num_slots);
+  memset(slot_usage, 1, num_slots);
   char* ptr = reinterpret_cast<char*>(internal::PartitionPage::ToPointer(page));
   // First, walk the freelist for this page and make a bitmap of which slots
   // are not in use.
@@ -564,7 +564,7 @@
       !bucket->num_full_pages)
     return;
 
-  SbMemorySet(stats_out, '\0', sizeof(*stats_out));
+  memset(stats_out, '\0', sizeof(*stats_out));
   stats_out->is_valid = true;
   stats_out->is_direct_map = false;
   stats_out->num_full_pages = static_cast<size_t>(bucket->num_full_pages);
diff --git a/src/base/allocator/partition_allocator/partition_alloc.h b/src/base/allocator/partition_allocator/partition_alloc.h
index 79b22f4..af49684 100644
--- a/src/base/allocator/partition_allocator/partition_alloc.h
+++ b/src/base/allocator/partition_allocator/partition_alloc.h
@@ -433,7 +433,7 @@
 class SizeSpecificPartitionAllocator {
  public:
   SizeSpecificPartitionAllocator() {
-    SbMemorySet(
+    memset(
         actual_buckets_, 0,
         sizeof(internal::PartitionBucket) * base::size(actual_buckets_));
   }
diff --git a/src/base/allocator/partition_allocator/partition_alloc_unittest.cc b/src/base/allocator/partition_allocator/partition_alloc_unittest.cc
index 5ba8414..cfc208d 100644
--- a/src/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/src/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -739,7 +739,7 @@
          kExtraAllocSize;
   ptr = generic_allocator.root()->Alloc(size, type_name);
   EXPECT_TRUE(ptr);
-  SbMemorySet(ptr, 'A', size);
+  memset(ptr, 'A', size);
   ptr2 = generic_allocator.root()->Alloc(size, type_name);
   EXPECT_TRUE(ptr2);
   void* ptr3 = generic_allocator.root()->Alloc(size, type_name);
@@ -871,7 +871,7 @@
   // realloc(0, size) should be equivalent to malloc().
   void* ptr =
       generic_allocator.root()->Realloc(nullptr, kTestAllocSize, type_name);
-  SbMemorySet(ptr, 'A', kTestAllocSize);
+  memset(ptr, 'A', kTestAllocSize);
   PartitionPage* page =
       PartitionPage::FromPointer(PartitionCookieFreePointerAdjust(ptr));
   // realloc(ptr, 0) should be equivalent to free().
@@ -884,7 +884,7 @@
   size_t size = kSystemPageSize - kExtraAllocSize;
   EXPECT_EQ(size, generic_allocator.root()->ActualSize(size));
   ptr = generic_allocator.root()->Alloc(size, type_name);
-  SbMemorySet(ptr, 'A', size);
+  memset(ptr, 'A', size);
   ptr2 = generic_allocator.root()->Realloc(ptr, size + 1, type_name);
   EXPECT_NE(ptr, ptr2);
   char* char_ptr2 = static_cast<char*>(ptr2);
@@ -1927,8 +1927,8 @@
         requested_size - kExtraAllocSize, type_name);
     void* ptr4 = generic_allocator.root()->Alloc(
         requested_size - kExtraAllocSize, type_name);
-    SbMemorySet(ptr1, 'A', requested_size - kExtraAllocSize);
-    SbMemorySet(ptr2, 'A', requested_size - kExtraAllocSize);
+    memset(ptr1, 'A', requested_size - kExtraAllocSize);
+    memset(ptr2, 'A', requested_size - kExtraAllocSize);
     generic_allocator.root()->Free(ptr2);
     generic_allocator.root()->Free(ptr1);
     {
@@ -1973,7 +1973,7 @@
   {
     char* ptr1 = reinterpret_cast<char*>(generic_allocator.root()->Alloc(
         (32 * kSystemPageSize) - kExtraAllocSize, type_name));
-    SbMemorySet(ptr1, 'A', (32 * kSystemPageSize) - kExtraAllocSize);
+    memset(ptr1, 'A', (32 * kSystemPageSize) - kExtraAllocSize);
     generic_allocator.root()->Free(ptr1);
     ptr1 = reinterpret_cast<char*>(generic_allocator.root()->Alloc(
         (31 * kSystemPageSize) - kExtraAllocSize, type_name));
@@ -2005,7 +2005,7 @@
   {
     char* ptr1 = reinterpret_cast<char*>(generic_allocator.root()->Alloc(
         (64 * kSystemPageSize) - kExtraAllocSize, type_name));
-    SbMemorySet(ptr1, 'A', (64 * kSystemPageSize) - kExtraAllocSize);
+    memset(ptr1, 'A', (64 * kSystemPageSize) - kExtraAllocSize);
     generic_allocator.root()->Free(ptr1);
     ptr1 = reinterpret_cast<char*>(generic_allocator.root()->Alloc(
         (61 * kSystemPageSize) - kExtraAllocSize, type_name));
@@ -2170,11 +2170,11 @@
   void* ptr = generic_allocator.root()->Alloc(kSize + 1, type_name);
   EXPECT_TRUE(ptr);
 
-  SbMemorySet(ptr, 0xbd, kSize + 1);
+  memset(ptr, 0xbd, kSize + 1);
   ptr = generic_allocator.root()->Realloc(ptr, kSize + 2, type_name);
   EXPECT_TRUE(ptr);
 
-  SbMemorySet(ptr, 0xbd, kSize + 2);
+  memset(ptr, 0xbd, kSize + 2);
   generic_allocator.root()->Free(ptr);
 }
 
diff --git a/src/base/allocator/partition_allocator/partition_page.h b/src/base/allocator/partition_allocator/partition_page.h
index 675f6e6..5addd74 100644
--- a/src/base/allocator/partition_allocator/partition_page.h
+++ b/src/base/allocator/partition_allocator/partition_page.h
@@ -211,7 +211,7 @@
   PartitionCookieCheckValue(reinterpret_cast<char*>(ptr) + slot_size -
                             kCookieSize);
 
-  SbMemorySet(ptr, kFreedByte, slot_size);
+  memset(ptr, kFreedByte, slot_size);
 #endif
 
   DCHECK(this->num_allocated_slots);
diff --git a/src/base/allocator/partition_allocator/partition_root_base.h b/src/base/allocator/partition_allocator/partition_root_base.h
index 70ae37a..6a444de 100644
--- a/src/base/allocator/partition_allocator/partition_root_base.h
+++ b/src/base/allocator/partition_allocator/partition_root_base.h
@@ -137,14 +137,14 @@
   // Fill the region kUninitializedByte or 0, and surround it with 2 cookies.
   PartitionCookieWriteValue(char_ret);
   if (!zero_fill) {
-    SbMemorySet(ret, kUninitializedByte, no_cookie_size);
+    memset(ret, kUninitializedByte, no_cookie_size);
   } else if (!is_already_zeroed) {
-    SbMemorySet(ret, 0, no_cookie_size);
+    memset(ret, 0, no_cookie_size);
   }
   PartitionCookieWriteValue(char_ret + kCookieSize + no_cookie_size);
 #else
   if (ret && zero_fill && !is_already_zeroed) {
-    SbMemorySet(ret, 0, size);
+    memset(ret, 0, size);
   }
 #endif
 
diff --git a/src/base/android/jni_android.cc b/src/base/android/jni_android.cc
index f202461..3fd2922 100644
--- a/src/base/android/jni_android.cc
+++ b/src/base/android/jni_android.cc
@@ -120,9 +120,9 @@
     // 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 = SbStringGetLength(class_name) + 1;
+    size_t bufsize = strlen(class_name) + 1;
     char dotted_name[bufsize];
-    SbMemoryMove(dotted_name, class_name, bufsize);
+    memmove(dotted_name, class_name, bufsize);
     for (size_t i = 0; i < bufsize; ++i) {
       if (dotted_name[i] == '/') {
         dotted_name[i] = '.';
diff --git a/src/base/android/jni_array_unittest.cc b/src/base/android/jni_array_unittest.cc
index a715f9f..207ff91 100644
--- a/src/base/android/jni_array_unittest.cc
+++ b/src/base/android/jni_array_unittest.cc
@@ -333,7 +333,7 @@
     snprintf(text, sizeof text, "%d", i);
     ScopedJavaLocalRef<jbyteArray> byte_array =
         ToJavaByteArray(env, reinterpret_cast<uint8_t*>(text),
-                        static_cast<size_t>(SbStringGetLength(text)));
+                        static_cast<size_t>(strlen(text)));
     ASSERT_TRUE(byte_array.obj());
 
     env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
diff --git a/src/base/android/orderfile/orderfile_instrumentation.cc b/src/base/android/orderfile/orderfile_instrumentation.cc
index 1d8b09c..8c2def6 100644
--- a/src/base/android/orderfile/orderfile_instrumentation.cc
+++ b/src/base/android/orderfile/orderfile_instrumentation.cc
@@ -293,9 +293,9 @@
   Disable();
   g_data_index = 0;
   for (int i = 0; i < kPhases; i++) {
-    SbMemorySet(reinterpret_cast<uint32_t*>(g_data[i].offsets), 0,
+    memset(reinterpret_cast<uint32_t*>(g_data[i].offsets), 0,
                 sizeof(uint32_t) * kBitfieldSize);
-    SbMemorySet(reinterpret_cast<uint32_t*>(g_data[i].ordered_offsets), 0,
+    memset(reinterpret_cast<uint32_t*>(g_data[i].ordered_offsets), 0,
                 sizeof(uint32_t) * kMaxElements);
     g_data[i].index.store(0);
   }
diff --git a/src/base/atomicops_unittest.cc b/src/base/atomicops_unittest.cc
index 3b333b7..9c683e5 100644
--- a/src/base/atomicops_unittest.cc
+++ b/src/base/atomicops_unittest.cc
@@ -26,8 +26,8 @@
   } s;
 
   AtomicType prev_word_value, next_word_value;
-  SbMemorySet(&prev_word_value, 0xFF, sizeof(AtomicType));
-  SbMemorySet(&next_word_value, 0xEE, sizeof(AtomicType));
+  memset(&prev_word_value, 0xFF, sizeof(AtomicType));
+  memset(&next_word_value, 0xEE, sizeof(AtomicType));
 
   s.prev_word = prev_word_value;
   s.count = 0;
@@ -164,7 +164,7 @@
 template <class AtomicType>
 static AtomicType TestFillValue() {
   AtomicType val = 0;
-  SbMemorySet(&val, 0xa5, sizeof(AtomicType));
+  memset(&val, 0xa5, sizeof(AtomicType));
   return val;
 }
 
diff --git a/src/base/big_endian.cc b/src/base/big_endian.cc
index 88978d4..a6e197f 100644
--- a/src/base/big_endian.cc
+++ b/src/base/big_endian.cc
@@ -22,7 +22,7 @@
 bool BigEndianReader::ReadBytes(void* out, size_t len) {
   if (ptr_ + len > end_)
     return false;
-  SbMemoryCopy(out, ptr_, len);
+  memcpy(out, ptr_, len);
   ptr_ += len;
   return true;
 }
@@ -73,7 +73,7 @@
 bool BigEndianWriter::WriteBytes(const void* buf, size_t len) {
   if (ptr_ + len > end_)
     return false;
-  SbMemoryCopy(ptr_, buf, len);
+  memcpy(ptr_, buf, len);
   ptr_ += len;
   return true;
 }
diff --git a/src/base/big_endian_unittest.cc b/src/base/big_endian_unittest.cc
index f0e13b8..4ebf12f 100644
--- a/src/base/big_endian_unittest.cc
+++ b/src/base/big_endian_unittest.cc
@@ -75,7 +75,7 @@
                       0xF, 0x1A, 0x2B, 0x3C };
   char data[sizeof(expected)];
   char buf[] = { 0x2, 0x3 };
-  SbMemorySet(data, 0, sizeof(data));
+  memset(data, 0, sizeof(data));
   BigEndianWriter writer(data, sizeof(data));
 
   EXPECT_TRUE(writer.Skip(2));
@@ -84,7 +84,7 @@
   EXPECT_TRUE(writer.WriteU16(0x0506));
   EXPECT_TRUE(writer.WriteU32(0x0708090A));
   EXPECT_TRUE(writer.WriteU64(0x0B0C0D0E0F1A2B3Cllu));
-  EXPECT_EQ(0, SbMemoryCompare(expected, data, sizeof(expected)));
+  EXPECT_EQ(0, memcmp(expected, data, sizeof(expected)));
 }
 
 TEST(BigEndianWriterTest, RespectsLength) {
diff --git a/src/base/bind_internal.h b/src/base/bind_internal.h
index 8f38935..07b9933 100644
--- a/src/base/bind_internal.h
+++ b/src/base/bind_internal.h
@@ -14,7 +14,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/template_util.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 
 #if defined(OS_MACOSX) && !HAS_FEATURE(objc_arc)
 #include "base/mac/scoped_block.h"
diff --git a/src/base/bit_cast.h b/src/base/bit_cast.h
index 87049ed..1c33e3e 100644
--- a/src/base/bit_cast.h
+++ b/src/base/bit_cast.h
@@ -72,7 +72,7 @@
                 "bit_cast requires the source type to be copyable");
 
   Dest dest;
-  SbMemoryCopy(&dest, &source, sizeof(dest));
+  memcpy(&dest, &source, sizeof(dest));
   return dest;
 }
 
diff --git a/src/base/build_time_unittest.cc b/src/base/build_time_unittest.cc
index c3ebe88..2ca77ad 100644
--- a/src/base/build_time_unittest.cc
+++ b/src/base/build_time_unittest.cc
@@ -12,7 +12,7 @@
 TEST(BuildTime, DateLooksValid) {
   char build_date[] = BUILD_DATE;
 
-  EXPECT_EQ(20u, SbStringGetLength(build_date));
+  EXPECT_EQ(20u, strlen(build_date));
   EXPECT_EQ(' ', build_date[3]);
   EXPECT_EQ(' ', build_date[6]);
   EXPECT_EQ(' ', build_date[11]);
diff --git a/src/base/containers/flat_map.h b/src/base/containers/flat_map.h
index 4f0de16..474a6cb 100644
--- a/src/base/containers/flat_map.h
+++ b/src/base/containers/flat_map.h
@@ -12,7 +12,6 @@
 #include "base/containers/flat_tree.h"
 #include "base/logging.h"
 #include "base/template_util.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
diff --git a/src/base/containers/flat_tree.h b/src/base/containers/flat_tree.h
index bca6cbd..8c7e5f0 100644
--- a/src/base/containers/flat_tree.h
+++ b/src/base/containers/flat_tree.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/template_util.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
diff --git a/src/base/containers/span.h b/src/base/containers/span.h
index ddcd8a0..c336d07 100644
--- a/src/base/containers/span.h
+++ b/src/base/containers/span.h
@@ -20,7 +20,6 @@
 
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
@@ -193,14 +192,14 @@
   }
 
   constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {
-    CHECK14(Extent == dynamic_extent || Extent == size);
+    CHECK(Extent == dynamic_extent || Extent == size);
   }
 
   // Artificially templatized to break ambiguity for span(ptr, 0).
   template <typename = void>
   constexpr span(T* begin, T* end) noexcept : span(begin, end - begin) {
     // Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
-    CHECK14(begin <= end);
+    CHECK(begin <= end);
   }
 
   template <
@@ -251,7 +250,7 @@
   constexpr span(const span<U, OtherExtent>& other)
       : span(other.data(), other.size()) {}
 
-  CONSTEXPR span& operator=(const span& other) noexcept = default;
+  constexpr span& operator=(const span& other) noexcept = default;
 
   ~span() noexcept = default;
 
@@ -260,7 +259,7 @@
   constexpr span<T, Count> first() const noexcept {
     static_assert(Extent == dynamic_extent || Count <= Extent,
                   "Count must not exceed Extent");
-    CHECK14(Extent != dynamic_extent || Count <= size());
+    CHECK(Extent != dynamic_extent || Count <= size());
     return {data(), Count};
   }
 
@@ -268,7 +267,7 @@
   constexpr span<T, Count> last() const noexcept {
     static_assert(Extent == dynamic_extent || Count <= Extent,
                   "Count must not exceed Extent");
-    CHECK14(Extent != dynamic_extent || Count <= size());
+    CHECK(Extent != dynamic_extent || Count <= size());
     return {data() + (size() - Count), Count};
   }
 
@@ -285,21 +284,21 @@
     static_assert(Extent == dynamic_extent || Count == dynamic_extent ||
                       Count <= Extent - Offset,
                   "Count must not exceed Extent - Offset");
-    CHECK14(Extent != dynamic_extent || Offset <= size());
-    CHECK14(Extent != dynamic_extent || Count == dynamic_extent ||
+    CHECK(Extent != dynamic_extent || Offset <= size());
+    CHECK(Extent != dynamic_extent || Count == dynamic_extent ||
             Count <= size() - Offset);
     return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset};
   }
 
   constexpr span<T, dynamic_extent> first(size_t count) const noexcept {
     // Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
-    CHECK14(count <= size());
+    CHECK(count <= size());
     return {data(), count};
   }
 
   constexpr span<T, dynamic_extent> last(size_t count) const noexcept {
     // Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
-    CHECK14(count <= size());
+    CHECK(count <= size());
     return {data() + (size() - count), count};
   }
 
@@ -307,8 +306,8 @@
                                             size_t count = dynamic_extent) const
       noexcept {
     // Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
-    CHECK14(offset <= size());
-    CHECK14(count == dynamic_extent || count <= size() - offset);
+    CHECK(offset <= size());
+    CHECK(count == dynamic_extent || count <= size() - offset);
     return {data() + offset, count != dynamic_extent ? count : size() - offset};
   }
 
@@ -320,13 +319,13 @@
   // [span.elem], span element access
   constexpr T& operator[](size_t idx) const noexcept {
     // Note: CHECK_LT is not constexpr, hence regular CHECK must be used.
-    CHECK14(idx < size());
+    CHECK(idx < size());
     return *(data() + idx);
   }
 
   constexpr T& operator()(size_t idx) const noexcept {
     // Note: CHECK_LT is not constexpr, hence regular CHECK must be used.
-    CHECK14(idx < size());
+    CHECK(idx < size());
     return *(data() + idx);
   }
 
@@ -368,7 +367,7 @@
 // [span.comparison], span comparison operators
 // Relational operators. Equality is a element-wise comparison.
 template <typename T, size_t X, typename U, size_t Y>
-CONSTEXPR bool operator==(span<T, X> lhs, span<U, Y> rhs) noexcept {
+constexpr bool operator==(span<T, X> lhs, span<U, Y> rhs) noexcept {
 #if __cplusplus < 201402L
   // With GNU at least, there exists an implementation of std::equal that is
   // replaced in C++14.
diff --git a/src/base/containers/span_unittest.cc b/src/base/containers/span_unittest.cc
index 9123743..dcfb9c8 100644
--- a/src/base/containers/span_unittest.cc
+++ b/src/base/containers/span_unittest.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -32,7 +31,7 @@
 }
 
 TEST(SpanTest, ConstructFromDataAndSize) {
-  CONSTEXPR span<int> empty_span(nullptr, 0);
+  constexpr span<int> empty_span(nullptr, 0);
   EXPECT_TRUE(empty_span.empty());
   EXPECT_EQ(nullptr, empty_span.data());
 
@@ -54,7 +53,7 @@
 }
 
 TEST(SpanTest, ConstructFromPointerPair) {
-  CONSTEXPR span<int> empty_span(nullptr, nullptr);
+  constexpr span<int> empty_span(nullptr, nullptr);
   EXPECT_TRUE(empty_span.empty());
   EXPECT_EQ(nullptr, empty_span.data());
 
@@ -78,25 +77,25 @@
 TEST(SpanTest, ConstructFromConstexprArray) {
   static constexpr int kArray[] = {5, 4, 3, 2, 1};
 
-  CONSTEXPR span<const int> dynamic_span(kArray);
-  STATIC_ASSERT(kArray == dynamic_span.data(), "");
-  STATIC_ASSERT(base::size(kArray) == dynamic_span.size(), "");
+  constexpr span<const int> dynamic_span(kArray);
+  static_assert(kArray == dynamic_span.data(), "");
+  static_assert(base::size(kArray) == dynamic_span.size(), "");
 
-  STATIC_ASSERT(kArray[0] == dynamic_span[0], "");
-  STATIC_ASSERT(kArray[1] == dynamic_span[1], "");
-  STATIC_ASSERT(kArray[2] == dynamic_span[2], "");
-  STATIC_ASSERT(kArray[3] == dynamic_span[3], "");
-  STATIC_ASSERT(kArray[4] == dynamic_span[4], "");
+  static_assert(kArray[0] == dynamic_span[0], "");
+  static_assert(kArray[1] == dynamic_span[1], "");
+  static_assert(kArray[2] == dynamic_span[2], "");
+  static_assert(kArray[3] == dynamic_span[3], "");
+  static_assert(kArray[4] == dynamic_span[4], "");
 
-  CONSTEXPR span<const int, base::size(kArray)> static_span(kArray);
-  STATIC_ASSERT(kArray == static_span.data(), "");
-  STATIC_ASSERT(base::size(kArray) == static_span.size(), "");
+  constexpr span<const int, base::size(kArray)> static_span(kArray);
+  static_assert(kArray == static_span.data(), "");
+  static_assert(base::size(kArray) == static_span.size(), "");
 
-  STATIC_ASSERT(kArray[0] == static_span[0], "");
-  STATIC_ASSERT(kArray[1] == static_span[1], "");
-  STATIC_ASSERT(kArray[2] == static_span[2], "");
-  STATIC_ASSERT(kArray[3] == static_span[3], "");
-  STATIC_ASSERT(kArray[4] == static_span[4], "");
+  static_assert(kArray[0] == static_span[0], "");
+  static_assert(kArray[1] == static_span[1], "");
+  static_assert(kArray[2] == static_span[2], "");
+  static_assert(kArray[3] == static_span[3], "");
+  static_assert(kArray[4] == static_span[4], "");
 }
 
 TEST(SpanTest, ConstructFromArray) {
@@ -283,191 +282,191 @@
 
 TEST(SpanTest, TemplatedFirst) {
   static constexpr int array[] = {1, 2, 3};
-  CONSTEXPR span<const int, 3> span(array);
+  constexpr span<const int, 3> span(array);
 
   {
-    CONSTEXPR auto subspan = span.first<0>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.first<0>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.first<1>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
+    constexpr auto subspan = span.first<1>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.first<2>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(2u == subspan.size(), "");
-    STATIC_ASSERT(2u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
+    constexpr auto subspan = span.first<2>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(2u == subspan.size(), "");
+    static_assert(2u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.first<3>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(3u == subspan.size(), "");
-    STATIC_ASSERT(3u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
-    STATIC_ASSERT(3 == subspan[2], "");
+    constexpr auto subspan = span.first<3>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(3u == subspan.size(), "");
+    static_assert(3u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
+    static_assert(3 == subspan[2], "");
   }
 }
 
 TEST(SpanTest, TemplatedLast) {
   static constexpr int array[] = {1, 2, 3};
-  CONSTEXPR span<const int, 3> span(array);
+  constexpr span<const int, 3> span(array);
 
   {
-    CONSTEXPR auto subspan = span.last<0>();
-    STATIC_ASSERT(span.data() + 3 == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.last<0>();
+    static_assert(span.data() + 3 == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.last<1>();
-    STATIC_ASSERT(span.data() + 2 == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(3 == subspan[0], "");
+    constexpr auto subspan = span.last<1>();
+    static_assert(span.data() + 2 == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(3 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.last<2>();
-    STATIC_ASSERT(span.data() + 1 == subspan.data(), "");
-    STATIC_ASSERT(2u == subspan.size(), "");
-    STATIC_ASSERT(2u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(2 == subspan[0], "");
-    STATIC_ASSERT(3 == subspan[1], "");
+    constexpr auto subspan = span.last<2>();
+    static_assert(span.data() + 1 == subspan.data(), "");
+    static_assert(2u == subspan.size(), "");
+    static_assert(2u == decltype(subspan)::extent, "");
+    static_assert(2 == subspan[0], "");
+    static_assert(3 == subspan[1], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.last<3>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(3u == subspan.size(), "");
-    STATIC_ASSERT(3u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
-    STATIC_ASSERT(3 == subspan[2], "");
+    constexpr auto subspan = span.last<3>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(3u == subspan.size(), "");
+    static_assert(3u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
+    static_assert(3 == subspan[2], "");
   }
 }
 
 TEST(SpanTest, TemplatedSubspan) {
   static constexpr int array[] = {1, 2, 3};
-  CONSTEXPR span<const int, 3> span(array);
+  constexpr span<const int, 3> span(array);
 
   {
-    CONSTEXPR auto subspan = span.subspan<0>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(3u == subspan.size(), "");
-    STATIC_ASSERT(3u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
-    STATIC_ASSERT(3 == subspan[2], "");
+    constexpr auto subspan = span.subspan<0>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(3u == subspan.size(), "");
+    static_assert(3u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
+    static_assert(3 == subspan[2], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<1>();
-    STATIC_ASSERT(span.data() + 1 == subspan.data(), "");
-    STATIC_ASSERT(2u == subspan.size(), "");
-    STATIC_ASSERT(2u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(2 == subspan[0], "");
-    STATIC_ASSERT(3 == subspan[1], "");
+    constexpr auto subspan = span.subspan<1>();
+    static_assert(span.data() + 1 == subspan.data(), "");
+    static_assert(2u == subspan.size(), "");
+    static_assert(2u == decltype(subspan)::extent, "");
+    static_assert(2 == subspan[0], "");
+    static_assert(3 == subspan[1], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<2>();
-    STATIC_ASSERT(span.data() + 2 == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(3 == subspan[0], "");
+    constexpr auto subspan = span.subspan<2>();
+    static_assert(span.data() + 2 == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(3 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<3>();
-    STATIC_ASSERT(span.data() + 3 == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.subspan<3>();
+    static_assert(span.data() + 3 == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<0, 0>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.subspan<0, 0>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<1, 0>();
-    STATIC_ASSERT(span.data() + 1 == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.subspan<1, 0>();
+    static_assert(span.data() + 1 == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<2, 0>();
-    STATIC_ASSERT(span.data() + 2 == subspan.data(), "");
-    STATIC_ASSERT(0u == subspan.size(), "");
-    STATIC_ASSERT(0u == decltype(subspan)::extent, "");
+    constexpr auto subspan = span.subspan<2, 0>();
+    static_assert(span.data() + 2 == subspan.data(), "");
+    static_assert(0u == subspan.size(), "");
+    static_assert(0u == decltype(subspan)::extent, "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<0, 1>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
+    constexpr auto subspan = span.subspan<0, 1>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<1, 1>();
-    STATIC_ASSERT(span.data() + 1 == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(2 == subspan[0], "");
+    constexpr auto subspan = span.subspan<1, 1>();
+    static_assert(span.data() + 1 == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(2 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<2, 1>();
-    STATIC_ASSERT(span.data() + 2 == subspan.data(), "");
-    STATIC_ASSERT(1u == subspan.size(), "");
-    STATIC_ASSERT(1u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(3 == subspan[0], "");
+    constexpr auto subspan = span.subspan<2, 1>();
+    static_assert(span.data() + 2 == subspan.data(), "");
+    static_assert(1u == subspan.size(), "");
+    static_assert(1u == decltype(subspan)::extent, "");
+    static_assert(3 == subspan[0], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<0, 2>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(2u == subspan.size(), "");
-    STATIC_ASSERT(2u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
+    constexpr auto subspan = span.subspan<0, 2>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(2u == subspan.size(), "");
+    static_assert(2u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<1, 2>();
-    STATIC_ASSERT(span.data() + 1 == subspan.data(), "");
-    STATIC_ASSERT(2u == subspan.size(), "");
-    STATIC_ASSERT(2u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(2 == subspan[0], "");
-    STATIC_ASSERT(3 == subspan[1], "");
+    constexpr auto subspan = span.subspan<1, 2>();
+    static_assert(span.data() + 1 == subspan.data(), "");
+    static_assert(2u == subspan.size(), "");
+    static_assert(2u == decltype(subspan)::extent, "");
+    static_assert(2 == subspan[0], "");
+    static_assert(3 == subspan[1], "");
   }
 
   {
-    CONSTEXPR auto subspan = span.subspan<0, 3>();
-    STATIC_ASSERT(span.data() == subspan.data(), "");
-    STATIC_ASSERT(3u == subspan.size(), "");
-    STATIC_ASSERT(3u == decltype(subspan)::extent, "");
-    STATIC_ASSERT(1 == subspan[0], "");
-    STATIC_ASSERT(2 == subspan[1], "");
-    STATIC_ASSERT(3 == subspan[2], "");
+    constexpr auto subspan = span.subspan<0, 3>();
+    static_assert(span.data() == subspan.data(), "");
+    static_assert(3u == subspan.size(), "");
+    static_assert(3u == decltype(subspan)::extent, "");
+    static_assert(1 == subspan[0], "");
+    static_assert(2 == subspan[1], "");
+    static_assert(3 == subspan[2], "");
   }
 }
 
@@ -871,24 +870,24 @@
 
 TEST(SpanTest, OperatorAt) {
   static constexpr int kArray[] = {1, 6, 1, 8, 0};
-  CONSTEXPR span<const int> span(kArray);
+  constexpr span<const int> span(kArray);
 
-  STATIC_ASSERT(kArray[0] == span[0], "span[0] does not equal kArray[0]");
-  STATIC_ASSERT(kArray[1] == span[1], "span[1] does not equal kArray[1]");
-  STATIC_ASSERT(kArray[2] == span[2], "span[2] does not equal kArray[2]");
-  STATIC_ASSERT(kArray[3] == span[3], "span[3] does not equal kArray[3]");
-  STATIC_ASSERT(kArray[4] == span[4], "span[4] does not equal kArray[4]");
+  static_assert(kArray[0] == span[0], "span[0] does not equal kArray[0]");
+  static_assert(kArray[1] == span[1], "span[1] does not equal kArray[1]");
+  static_assert(kArray[2] == span[2], "span[2] does not equal kArray[2]");
+  static_assert(kArray[3] == span[3], "span[3] does not equal kArray[3]");
+  static_assert(kArray[4] == span[4], "span[4] does not equal kArray[4]");
 
-  STATIC_ASSERT(kArray[0] == span(0), "span(0) does not equal kArray[0]");
-  STATIC_ASSERT(kArray[1] == span(1), "span(1) does not equal kArray[1]");
-  STATIC_ASSERT(kArray[2] == span(2), "span(2) does not equal kArray[2]");
-  STATIC_ASSERT(kArray[3] == span(3), "span(3) does not equal kArray[3]");
-  STATIC_ASSERT(kArray[4] == span(4), "span(4) does not equal kArray[4]");
+  static_assert(kArray[0] == span(0), "span(0) does not equal kArray[0]");
+  static_assert(kArray[1] == span(1), "span(1) does not equal kArray[1]");
+  static_assert(kArray[2] == span(2), "span(2) does not equal kArray[2]");
+  static_assert(kArray[3] == span(3), "span(3) does not equal kArray[3]");
+  static_assert(kArray[4] == span(4), "span(4) does not equal kArray[4]");
 }
 
 TEST(SpanTest, Iterator) {
   static constexpr int kArray[] = {1, 6, 1, 8, 0};
-  CONSTEXPR span<const int> span(kArray);
+  constexpr span<const int> span(kArray);
 
   std::vector<int> results;
   for (int i : span)
@@ -898,7 +897,7 @@
 
 TEST(SpanTest, ReverseIterator) {
   static constexpr int kArray[] = {1, 6, 1, 8, 0};
-  CONSTEXPR span<const int> span(kArray);
+  constexpr span<const int> span(kArray);
 
 #if __cplusplus < 201402L
   // With GNU at least, there exists an implementation of std::equal that is
@@ -937,13 +936,13 @@
 TEST(SpanTest, Equality) {
   static constexpr int kArray1[] = {3, 1, 4, 1, 5};
   static constexpr int kArray2[] = {3, 1, 4, 1, 5};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 5> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 5> span2(kArray2);
 
   EXPECT_EQ(span1, span2);
 
   static constexpr int kArray3[] = {2, 7, 1, 8, 3};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 == span3);
 
@@ -956,13 +955,13 @@
 TEST(SpanTest, Inequality) {
   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
   static constexpr int kArray2[] = {1, 4, 6, 8, 9};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 5> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 5> span2(kArray2);
 
   EXPECT_NE(span1, span2);
 
   static constexpr int kArray3[] = {2, 3, 5, 7, 11};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 != span3);
 
@@ -975,13 +974,13 @@
 TEST(SpanTest, LessThan) {
   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
   static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 6> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 6> span2(kArray2);
 
   EXPECT_LT(span1, span2);
 
   static constexpr int kArray3[] = {2, 3, 5, 7, 11};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 < span3);
 
@@ -994,14 +993,14 @@
 TEST(SpanTest, LessEqual) {
   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
   static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 6> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 6> span2(kArray2);
 
   EXPECT_LE(span1, span1);
   EXPECT_LE(span1, span2);
 
   static constexpr int kArray3[] = {2, 3, 5, 7, 10};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 <= span3);
 
@@ -1014,13 +1013,13 @@
 TEST(SpanTest, GreaterThan) {
   static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
   static constexpr int kArray2[] = {2, 3, 5, 7, 11};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 5> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 5> span2(kArray2);
 
   EXPECT_GT(span1, span2);
 
   static constexpr int kArray3[] = {2, 3, 5, 7, 11, 13};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 > span3);
 
@@ -1033,14 +1032,14 @@
 TEST(SpanTest, GreaterEqual) {
   static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
   static constexpr int kArray2[] = {2, 3, 5, 7, 11};
-  CONSTEXPR span<const int> span1(kArray1);
-  CONSTEXPR span<const int, 5> span2(kArray2);
+  constexpr span<const int> span1(kArray1);
+  constexpr span<const int, 5> span2(kArray2);
 
   EXPECT_GE(span1, span1);
   EXPECT_GE(span1, span2);
 
   static constexpr int kArray3[] = {2, 3, 5, 7, 12};
-  CONSTEXPR span<const int> span3(kArray3);
+  constexpr span<const int> span3(kArray3);
 
   EXPECT_FALSE(span1 >= span3);
 
@@ -1112,7 +1111,7 @@
 
 TEST(SpanTest, MakeSpanFromConstexprArray) {
   static constexpr int kArray[] = {1, 2, 3, 4, 5};
-  CONSTEXPR span<const int> span(kArray);
+  constexpr span<const int> span(kArray);
   EXPECT_EQ(span, make_span(kArray));
   static_assert(decltype(make_span(kArray))::extent == 5, "");
 }
@@ -1160,60 +1159,60 @@
 
 TEST(SpanTest, MakeSpanFromDynamicSpan) {
   static constexpr int kArray[] = {1, 2, 3, 4, 5};
-  CONSTEXPR span<const int> span(kArray);
+  constexpr span<const int> span(kArray);
   static_assert(std::is_same<decltype(span)::element_type,
                              decltype(make_span(span))::element_type>::value,
                 "make_span(span) should have the same element_type as span");
 
-  STATIC_ASSERT(span.data() == make_span(span).data(),
+  static_assert(span.data() == make_span(span).data(),
                 "make_span(span) should have the same data() as span");
 
-  STATIC_ASSERT(span.size() == make_span(span).size(),
+  static_assert(span.size() == make_span(span).size(),
                 "make_span(span) should have the same size() as span");
 
-  STATIC_ASSERT(decltype(make_span(span))::extent == decltype(span)::extent,
+  static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
                 "make_span(span) should have the same extent as span");
 }
 
 TEST(SpanTest, MakeSpanFromStaticSpan) {
   static constexpr int kArray[] = {1, 2, 3, 4, 5};
-  CONSTEXPR span<const int, 5> span(kArray);
+  constexpr span<const int, 5> span(kArray);
   static_assert(std::is_same<decltype(span)::element_type,
                              decltype(make_span(span))::element_type>::value,
                 "make_span(span) should have the same element_type as span");
 
-  STATIC_ASSERT(span.data() == make_span(span).data(),
+  static_assert(span.data() == make_span(span).data(),
                 "make_span(span) should have the same data() as span");
 
-  STATIC_ASSERT(span.size() == make_span(span).size(),
+  static_assert(span.size() == make_span(span).size(),
                 "make_span(span) should have the same size() as span");
 
-  STATIC_ASSERT(decltype(make_span(span))::extent == decltype(span)::extent,
+  static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
                 "make_span(span) should have the same extent as span");
 }
 
 TEST(SpanTest, EnsureConstexprGoodness) {
   static constexpr int kArray[] = {5, 4, 3, 2, 1};
-  CONSTEXPR span<const int> constexpr_span(kArray);
+  constexpr span<const int> constexpr_span(kArray);
   const size_t size = 2;
 
   const size_t start = 1;
-  CONSTEXPR span<const int> subspan =
+  constexpr span<const int> subspan =
       constexpr_span.subspan(start, start + size);
   for (size_t i = 0; i < subspan.size(); ++i)
     EXPECT_EQ(kArray[start + i], subspan[i]);
 
-  CONSTEXPR span<const int> firsts = constexpr_span.first(size);
+  constexpr span<const int> firsts = constexpr_span.first(size);
   for (size_t i = 0; i < firsts.size(); ++i)
     EXPECT_EQ(kArray[i], firsts[i]);
 
-  CONSTEXPR span<const int> lasts = constexpr_span.last(size);
+  constexpr span<const int> lasts = constexpr_span.last(size);
   for (size_t i = 0; i < lasts.size(); ++i) {
     const size_t j = (arraysize(kArray) - size) + i;
     EXPECT_EQ(kArray[j], lasts[i]);
   }
 
-  CONSTEXPR int item = constexpr_span[size];
+  constexpr int item = constexpr_span[size];
   EXPECT_EQ(kArray[size], item);
 }
 
diff --git a/src/base/containers/stack_container_unittest.cc b/src/base/containers/stack_container_unittest.cc
index 20c3ccd..56cc42f 100644
--- a/src/base/containers/stack_container_unittest.cc
+++ b/src/base/containers/stack_container_unittest.cc
@@ -105,7 +105,7 @@
 template <size_t alignment>
 class AlignedData {
  public:
-  AlignedData() { SbMemorySet(data_, 0, alignment); }
+  AlignedData() { memset(data_, 0, alignment); }
   ~AlignedData() = default;
   alignas(alignment) char data_[alignment];
 };
diff --git a/src/base/containers/vector_buffer.h b/src/base/containers/vector_buffer.h
index 2a60383..ea1caa3 100644
--- a/src/base/containers/vector_buffer.h
+++ b/src/base/containers/vector_buffer.h
@@ -128,7 +128,7 @@
                                     int>::type = 0>
   static void MoveRange(T* from_begin, T* from_end, T* to) {
     CHECK(!RangesOverlap(from_begin, from_end, to));
-    SbMemoryCopy(
+    memcpy(
         to, from_begin,
         CheckSub(get_uintptr(from_end), get_uintptr(from_begin)).ValueOrDie());
   }
diff --git a/src/base/cpu.cc b/src/base/cpu.cc
index 42ccf16..52fed28 100644
--- a/src/base/cpu.cc
+++ b/src/base/cpu.cc
@@ -115,14 +115,14 @@
     std::istringstream iss(contents);
     std::string line;
     while (std::getline(iss, line)) {
-      if (line.compare(0, SbStringGetLength(kModelNamePrefix),
+      if (line.compare(0, strlen(kModelNamePrefix),
                        kModelNamePrefix) == 0)
         return new std::string(
-            line.substr(SbStringGetLength(kModelNamePrefix)));
-      if (line.compare(0, SbStringGetLength(kProcessorPrefix),
+            line.substr(strlen(kModelNamePrefix)));
+      if (line.compare(0, strlen(kProcessorPrefix),
                        kProcessorPrefix) == 0)
         return new std::string(
-            line.substr(SbStringGetLength(kProcessorPrefix)));
+            line.substr(strlen(kProcessorPrefix)));
     }
 
     return new std::string();
@@ -157,7 +157,7 @@
   static constexpr size_t kVendorNameSize = 3 * sizeof(cpu_info[1]);
   static_assert(kVendorNameSize < arraysize(cpu_string),
                 "cpu_string too small");
-  SbMemoryCopy(cpu_string, &cpu_info[1], kVendorNameSize);
+  memcpy(cpu_string, &cpu_info[1], kVendorNameSize);
   cpu_string[kVendorNameSize] = '\0';
   cpu_vendor_ = cpu_string;
 
@@ -218,7 +218,7 @@
     for (int parameter = kParameterStart; parameter <= kParameterEnd;
          ++parameter) {
       __cpuid(cpu_info, parameter);
-      SbMemoryCopy(&cpu_string[i], cpu_info, sizeof(cpu_info));
+      memcpy(&cpu_string[i], cpu_info, sizeof(cpu_info));
       i += sizeof(cpu_info);
     }
     cpu_string[i] = '\0';
diff --git a/src/base/debug/activity_analyzer_unittest.cc b/src/base/debug/activity_analyzer_unittest.cc
index 3dac24f..2393178 100644
--- a/src/base/debug/activity_analyzer_unittest.cc
+++ b/src/base/debug/activity_analyzer_unittest.cc
@@ -36,7 +36,7 @@
 class TestActivityTracker : public ThreadActivityTracker {
  public:
   TestActivityTracker(std::unique_ptr<char[]> memory, size_t mem_size)
-      : ThreadActivityTracker(SbMemorySet(memory.get(), 0, mem_size), mem_size),
+      : ThreadActivityTracker(memset(memory.get(), 0, mem_size), mem_size),
         mem_segment_(std::move(memory)) {}
 
   ~TestActivityTracker() override = default;
@@ -318,7 +318,7 @@
       EXPECT_EQ(sizeof(string2a), user_data.at("ref2").GetReference().size());
       ASSERT_TRUE(ContainsKey(user_data, "sref2"));
       EXPECT_EQ(string2b, user_data.at("sref2").GetStringReference().data());
-      EXPECT_EQ(SbStringGetLength(string2b),
+      EXPECT_EQ(strlen(string2b),
                 user_data.at("sref2").GetStringReference().size());
     }
 
@@ -342,7 +342,7 @@
     EXPECT_EQ(string1a, user_data.at("ref1").GetReference().data());
     EXPECT_EQ(sizeof(string1a), user_data.at("ref1").GetReference().size());
     EXPECT_EQ(string1b, user_data.at("sref1").GetStringReference().data());
-    EXPECT_EQ(SbStringGetLength(string1b),
+    EXPECT_EQ(strlen(string1b),
               user_data.at("sref1").GetStringReference().size());
   }
 
@@ -396,7 +396,7 @@
   EXPECT_EQ(sizeof(string1), snapshot.at("ref").GetReference().size());
   ASSERT_TRUE(ContainsKey(snapshot, "sref"));
   EXPECT_EQ(string2, snapshot.at("sref").GetStringReference().data());
-  EXPECT_EQ(SbStringGetLength(string2),
+  EXPECT_EQ(strlen(string2),
             snapshot.at("sref").GetStringReference().size());
 }
 
diff --git a/src/base/debug/activity_tracker.cc b/src/base/debug/activity_tracker.cc
index 91236a7..1476d1a 100644
--- a/src/base/debug/activity_tracker.cc
+++ b/src/base/debug/activity_tracker.cc
@@ -518,7 +518,7 @@
     char* name_memory = reinterpret_cast<char*>(header) + sizeof(FieldHeader);
     void* value_memory =
         reinterpret_cast<char*>(header) + sizeof(FieldHeader) + name_extent;
-    SbMemoryCopy(name_memory, name.data(), name_size);
+    memcpy(name_memory, name.data(), name_size);
     header->type.store(type, std::memory_order_release);
 
     // Create an entry in |values_| so that this field can be found and changed
@@ -541,7 +541,7 @@
   DCHECK_EQ(type, info->type);
   size = std::min(size, info->extent);
   info->size_ptr->store(0, std::memory_order_seq_cst);
-  SbMemoryCopy(info->memory, memory, size);
+  memcpy(info->memory, memory, size);
   info->size_ptr->store(size, std::memory_order_release);
 }
 
@@ -955,12 +955,12 @@
     output_snapshot->activity_stack.resize(count);
     if (count > 0) {
       // Copy the existing contents. Memcpy is used for speed.
-      SbMemoryCopy(&output_snapshot->activity_stack[0], stack_,
+      memcpy(&output_snapshot->activity_stack[0], stack_,
                    count * sizeof(Activity));
     }
 
     // Capture the last exception.
-    SbMemoryCopy(&output_snapshot->last_exception, &header_->last_exception,
+    memcpy(&output_snapshot->last_exception, &header_->last_exception,
                  sizeof(Activity));
 
     // TODO(bcwhite): Snapshot other things here.
@@ -984,7 +984,7 @@
     // if the trailing NUL were missing. Now limit the length if the actual
     // name is shorter.
     output_snapshot->thread_name.resize(
-        SbStringGetLength(output_snapshot->thread_name.c_str()));
+        strlen(output_snapshot->thread_name.c_str()));
 
     // If the data ID has changed then the tracker has exited and the memory
     // reused by a new one. Try again.
@@ -1125,7 +1125,7 @@
   info->size = static_cast<size_t>(size);
   info->timestamp = timestamp;
   info->age = age;
-  SbMemoryCopy(info->identifier, identifier, sizeof(info->identifier));
+  memcpy(info->identifier, identifier, sizeof(info->identifier));
 
   if (offsetof(ModuleInfoRecord, pickle) + pickle_size > record_size)
     return false;
@@ -1151,8 +1151,8 @@
   record->size = info.size;
   record->timestamp = info.timestamp;
   record->age = info.age;
-  SbMemoryCopy(record->identifier, info.identifier, sizeof(identifier));
-  SbMemoryCopy(record->pickle, pickler.data(), pickler.size());
+  memcpy(record->identifier, info.identifier, sizeof(identifier));
+  memcpy(record->pickle, pickler.data(), pickler.size());
   record->pickle_size = pickler.size();
   record->changes.store(0, std::memory_order_relaxed);
 
@@ -1611,7 +1611,7 @@
   char* memory = allocator_->GetAsArray<char>(ref, kTypeIdGlobalLogMessage,
                                               message.size() + 1);
   if (memory) {
-    SbMemoryCopy(memory, message.data(), message.size());
+    memcpy(memory, message.data(), message.size());
     allocator_->MakeIterable(ref);
   }
 }
diff --git a/src/base/debug/activity_tracker_unittest.cc b/src/base/debug/activity_tracker_unittest.cc
index 841354c..4110b5d 100644
--- a/src/base/debug/activity_tracker_unittest.cc
+++ b/src/base/debug/activity_tracker_unittest.cc
@@ -32,7 +32,7 @@
 class TestActivityTracker : public ThreadActivityTracker {
  public:
   TestActivityTracker(std::unique_ptr<char[]> memory, size_t mem_size)
-      : ThreadActivityTracker(SbMemorySet(memory.get(), 0, mem_size), mem_size),
+      : ThreadActivityTracker(memset(memory.get(), 0, mem_size), mem_size),
         mem_segment_(std::move(memory)) {}
 
   ~TestActivityTracker() override = default;
@@ -110,7 +110,7 @@
 
 TEST_F(ActivityTrackerTest, UserDataTest) {
   char buffer[256];
-  SbMemorySet(buffer, 0, sizeof(buffer));
+  memset(buffer, 0, sizeof(buffer));
   ActivityUserData data(buffer, sizeof(buffer));
   size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader);
   ASSERT_EQ(space, data.available_);
@@ -519,7 +519,7 @@
   // Make a copy of the thread-tracker state so it can be restored later.
   const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref);
   std::unique_ptr<char[]> tracker_copy(new char[tracker_size]);
-  SbMemoryCopy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size);
+  memcpy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size);
 
   // Change the objects to appear to be owned by another process. Use a "past"
   // time so that exit-time is always later than create-time.
@@ -569,7 +569,7 @@
 
   // Restore memory contents and types so things don't crash when doing real
   // process clean-up.
-  SbMemoryCopy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(),
+  memcpy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(),
                tracker_size);
   global->allocator()->ChangeType(
       proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord,
diff --git a/src/base/debug/invalid_access_win.cc b/src/base/debug/invalid_access_win.cc
index 4b8ea60..393d8b2 100644
--- a/src/base/debug/invalid_access_win.cc
+++ b/src/base/debug/invalid_access_win.cc
@@ -41,7 +41,7 @@
     CHECK(addr);
     // Corrupt heap header.
     char* addr_mutable = reinterpret_cast<char*>(addr);
-    SbMemorySet(addr_mutable - sizeof(addr), 0xCC, sizeof(addr));
+    memset(addr_mutable - sizeof(addr), 0xCC, sizeof(addr));
 
     HeapFree(heap, 0, addr);
     HeapDestroy(heap);
diff --git a/src/base/debug/stack_trace.cc b/src/base/debug/stack_trace.cc
index d273b99..97cf8fb 100644
--- a/src/base/debug/stack_trace.cc
+++ b/src/base/debug/stack_trace.cc
@@ -209,7 +209,7 @@
 StackTrace::StackTrace(const void* const* trace, size_t count) {
   count = std::min(count, arraysize(trace_));
   if (count)
-    SbMemoryCopy(trace_, trace, count * sizeof(trace_[0]));
+    memcpy(trace_, trace, count * sizeof(trace_[0]));
   count_ = count;
 }
 
diff --git a/src/base/debug/stack_trace_android.cc b/src/base/debug/stack_trace_android.cc
index 80111ab..a9cda92 100644
--- a/src/base/debug/stack_trace_android.cc
+++ b/src/base/debug/stack_trace_android.cc
@@ -64,7 +64,7 @@
   // with SIGPIPE ignored as well.
   // TODO(phajdan.jr): De-duplicate this SIGPIPE code.
   struct sigaction action;
-  SbMemorySet(&action, 0, sizeof(action));
+  memset(&action, 0, sizeof(action));
   action.sa_handler = SIG_IGN;
   sigemptyset(&action.sa_mask);
   return (sigaction(SIGPIPE, &action, NULL) == 0);
diff --git a/src/base/debug/stack_trace_fuchsia.cc b/src/base/debug/stack_trace_fuchsia.cc
index 0cc657a..e57b867 100644
--- a/src/base/debug/stack_trace_fuchsia.cc
+++ b/src/base/debug/stack_trace_fuchsia.cc
@@ -106,7 +106,7 @@
   // if we keep hitting problems with truncation, find a way to plumb argv[0]
   // through to here instead, e.g. using CommandLine::GetProgramName().
   char app_name[arraysize(SymbolMap::Entry::name)];
-  SbStringCopyUnsafe(app_name, kProcessNamePrefix);
+  strcpy(app_name, kProcessNamePrefix);
   zx_status_t status = zx_object_get_property(
       process, ZX_PROP_NAME, app_name + kProcessNamePrefixLen,
       sizeof(app_name) - kProcessNamePrefixLen);
diff --git a/src/base/debug/stack_trace_posix.cc b/src/base/debug/stack_trace_posix.cc
index cac9539..72144e5 100644
--- a/src/base/debug/stack_trace_posix.cc
+++ b/src/base/debug/stack_trace_posix.cc
@@ -116,7 +116,7 @@
       // Insert the demangled symbol.
       text->insert(mangled_start, demangled_symbol.get());
       // Next time, we'll start right after the demangled symbol we inserted.
-      search_from = mangled_start + SbStringGetLength(demangled_symbol.get());
+      search_from = mangled_start + strlen(demangled_symbol.get());
     } else {
       // Failed to demangle.  Retry after the "_Z" we just found.
       search_from = mangled_start + 2;
@@ -223,7 +223,7 @@
   // NOTE: This code MUST be async-signal safe (it's used by in-process
   // stack dumping signal handler). NO malloc or stdio is allowed here.
   ignore_result(
-      HANDLE_EINTR(write(STDERR_FILENO, output, SbStringGetLength(output))));
+      HANDLE_EINTR(write(STDERR_FILENO, output, strlen(output))));
 }
 
 void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) {
@@ -242,7 +242,7 @@
     // replaced this signal handler upon entry, but we want to stay
     // installed. Thus, we reinstall ourselves before returning.
     struct sigaction action;
-    SbMemorySet(&action, 0, sizeof(action));
+    memset(&action, 0, sizeof(action));
     action.sa_flags = SA_RESETHAND | SA_SIGINFO;
     action.sa_sigaction = &StackDumpSignalHandler;
     sigemptyset(&action.sa_mask);
@@ -587,7 +587,7 @@
         start_address = region.start;
         base_address = region.base;
         if (file_path && file_path_size > 0) {
-          SbStringCopy(file_path, region.path.c_str(), file_path_size);
+          strncpy(file_path, region.path.c_str(), file_path_size);
           // Ensure null termination.
           file_path[file_path_size - 1] = '\0';
         }
@@ -615,7 +615,7 @@
       static_assert(SELFMAG <= sizeof(ElfW(Ehdr)), "SELFMAG too large");
       if ((r.permissions & MappedMemoryRegion::READ) &&
           safe_memcpy(&ehdr, r.start, sizeof(ElfW(Ehdr))) &&
-          SbMemoryCompare(ehdr.e_ident, ELFMAG, SELFMAG) == 0) {
+          memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) {
         switch (ehdr.e_type) {
           case ET_EXEC:
             cur_base = 0;
@@ -778,7 +778,7 @@
   // to be ignored.  Therefore, when testing that same code, it should run
   // with SIGPIPE ignored as well.
   struct sigaction sigpipe_action;
-  SbMemorySet(&sigpipe_action, 0, sizeof(sigpipe_action));
+  memset(&sigpipe_action, 0, sizeof(sigpipe_action));
   sigpipe_action.sa_handler = SIG_IGN;
   sigemptyset(&sigpipe_action.sa_mask);
   bool success = (sigaction(SIGPIPE, &sigpipe_action, nullptr) == 0);
@@ -787,7 +787,7 @@
   WarmUpBacktrace();
 
   struct sigaction action;
-  SbMemorySet(&action, 0, sizeof(action));
+  memset(&action, 0, sizeof(action));
   action.sa_flags = SA_RESETHAND | SA_SIGINFO;
   action.sa_sigaction = &StackDumpSignalHandler;
   sigemptyset(&action.sa_mask);
diff --git a/src/base/debug/stack_trace_win.cc b/src/base/debug/stack_trace_win.cc
index 2faa624..a24662d 100644
--- a/src/base/debug/stack_trace_win.cc
+++ b/src/base/debug/stack_trace_win.cc
@@ -215,7 +215,7 @@
           kMaxNameLength * sizeof(wchar_t) +
           sizeof(ULONG64) - 1) /
         sizeof(ULONG64)];
-      SbMemorySet(buffer, 0, sizeof(buffer));
+      memset(buffer, 0, sizeof(buffer));
 
       // Initialize symbol information retrieval structures.
       DWORD64 sym_displacement = 0;
@@ -308,14 +308,14 @@
   // context may have had more register state (YMM, etc) than we need to unwind
   // the stack. Typically StackWalk64 only needs integer and control registers.
   CONTEXT context_copy;
-  SbMemoryCopy(&context_copy, context_record, sizeof(context_copy));
+  memcpy(&context_copy, context_record, sizeof(context_copy));
   context_copy.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
 
   // When walking an exception stack, we need to use StackWalk64().
   count_ = 0;
   // Initialize stack walking.
   STACKFRAME64 stack_frame;
-  SbMemorySet(&stack_frame, 0, sizeof(stack_frame));
+  memset(&stack_frame, 0, sizeof(stack_frame));
 #if defined(_WIN64)
   int machine_type = IMAGE_FILE_MACHINE_AMD64;
   stack_frame.AddrPC.Offset = context_record->Rip;
diff --git a/src/base/debug/thread_heap_usage_tracker.cc b/src/base/debug/thread_heap_usage_tracker.cc
index e2df48a..77fcb2b 100644
--- a/src/base/debug/thread_heap_usage_tracker.cc
+++ b/src/base/debug/thread_heap_usage_tracker.cc
@@ -234,7 +234,7 @@
     allocator_usage = new ThreadHeapUsage();
     static_assert(std::is_pod<ThreadHeapUsage>::value,
                   "AllocatorDispatch must be POD");
-    SbMemorySet(allocator_usage, 0, sizeof(*allocator_usage));
+    memset(allocator_usage, 0, sizeof(*allocator_usage));
     ThreadAllocationUsage().Set(allocator_usage);
   }
 
@@ -268,7 +268,7 @@
   // instance persists the outer scope's usage stats. On destruction, this
   // instance will restore the outer scope's usage stats with this scope's
   // usage added.
-  SbMemorySet(thread_usage_, 0, sizeof(*thread_usage_));
+  memset(thread_usage_, 0, sizeof(*thread_usage_));
 }
 
 void ThreadHeapUsageTracker::Stop(bool usage_is_exclusive) {
diff --git a/src/base/environment.cc b/src/base/environment.cc
index 31954d4..4bfb484 100644
--- a/src/base/environment.cc
+++ b/src/base/environment.cc
@@ -233,7 +233,7 @@
   char* storage_data = reinterpret_cast<char*>(
       &result.get()[result_indices.size() + 1]);
   if (!value_storage.empty())
-    SbMemoryCopy(storage_data, value_storage.data(), value_storage.size());
+    memcpy(storage_data, value_storage.data(), value_storage.size());
 
   // Fill array of pointers at the beginning of the result.
   for (size_t i = 0; i < result_indices.size(); i++)
diff --git a/src/base/feature_list.cc b/src/base/feature_list.cc
index 3472a40..d8e00ac 100644
--- a/src/base/feature_list.cc
+++ b/src/base/feature_list.cc
@@ -185,7 +185,7 @@
     entry->pickle_size = pickle.size();
 
     char* dst = reinterpret_cast<char*>(entry) + sizeof(FeatureEntry);
-    SbMemoryCopy(dst, pickle.data(), pickle.size());
+    memcpy(dst, pickle.data(), pickle.size());
 
     allocator->MakeIterable(entry);
   }
diff --git a/src/base/files/dir_reader_linux.h b/src/base/files/dir_reader_linux.h
index 8fc91f7..acce538 100644
--- a/src/base/files/dir_reader_linux.h
+++ b/src/base/files/dir_reader_linux.h
@@ -34,7 +34,7 @@
       : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)),
         offset_(0),
         size_(0) {
-    SbMemorySet(buf_, 0, sizeof(buf_));
+    memset(buf_, 0, sizeof(buf_));
   }
 
   ~DirReaderLinux() {
diff --git a/src/base/files/file_enumerator_posix.cc b/src/base/files/file_enumerator_posix.cc
index 732964c..cea5e22 100644
--- a/src/base/files/file_enumerator_posix.cc
+++ b/src/base/files/file_enumerator_posix.cc
@@ -27,7 +27,7 @@
     // symlinks.
     if (!(errno == ENOENT && !show_links))
       DPLOG(ERROR) << "Couldn't stat" << path.value();
-    SbMemorySet(st, 0, sizeof(*st));
+    memset(st, 0, sizeof(*st));
   }
 }
 
@@ -36,7 +36,7 @@
 // FileEnumerator::FileInfo ----------------------------------------------------
 
 FileEnumerator::FileInfo::FileInfo() {
-  SbMemorySet(&stat_, 0, sizeof(stat_));
+  memset(&stat_, 0, sizeof(stat_));
 }
 
 bool FileEnumerator::FileInfo::IsDirectory() const {
diff --git a/src/base/files/file_enumerator_starboard.cc b/src/base/files/file_enumerator_starboard.cc
index 23047ca..386b2dd 100644
--- a/src/base/files/file_enumerator_starboard.cc
+++ b/src/base/files/file_enumerator_starboard.cc
@@ -27,7 +27,7 @@
 // FileEnumerator::FileInfo ----------------------------------------------------
 
 FileEnumerator::FileInfo::FileInfo() {
-  SbMemorySet(&sb_info_, 0, sizeof(sb_info_));
+  memset(&sb_info_, 0, sizeof(sb_info_));
 }
 
 bool FileEnumerator::FileInfo::IsDirectory() const {
@@ -102,7 +102,7 @@
     // TODO: Make sure this follows symlinks on relevant platforms.
     if (!SbFileGetPathInfo(full_name.value().c_str(), &info.sb_info_)) {
       DPLOG(ERROR) << "Couldn't SbFileGetInfo on " << full_name.value();
-      SbMemorySet(&info.sb_info_, 0, sizeof(info.sb_info_));
+      memset(&info.sb_info_, 0, sizeof(info.sb_info_));
     }
     return info;
   };
@@ -119,7 +119,7 @@
 
   while (SbDirectoryGetNext(dir, entry.data(), entry.size())) {
     const char dot_dot_str[] = "..";
-    if (!SbStringCompare(entry.data(), dot_dot_str, sizeof(dot_dot_str))) {
+    if (!strncmp(entry.data(), dot_dot_str, sizeof(dot_dot_str))) {
       found_dot_dot = true;
     }
     ret.push_back(GenerateEntry(entry.data()));
@@ -129,7 +129,7 @@
 
   while (SbDirectoryGetNext(dir, &entry)) {
     const char dot_dot_str[] = "..";
-    if (!SbStringCompare(entry.name, dot_dot_str, sizeof(dot_dot_str))) {
+    if (!strncmp(entry.name, dot_dot_str, sizeof(dot_dot_str))) {
       found_dot_dot = true;
     }
     ret.push_back(GenerateEntry(entry.name));
diff --git a/src/base/files/file_enumerator_win.cc b/src/base/files/file_enumerator_win.cc
index 1c0a2d2..b299eb0 100644
--- a/src/base/files/file_enumerator_win.cc
+++ b/src/base/files/file_enumerator_win.cc
@@ -36,7 +36,7 @@
 // FileEnumerator::FileInfo ----------------------------------------------------
 
 FileEnumerator::FileInfo::FileInfo() {
-  SbMemorySet(&find_data_, 0, sizeof(find_data_));
+  memset(&find_data_, 0, sizeof(find_data_));
 }
 
 bool FileEnumerator::FileInfo::IsDirectory() const {
@@ -92,7 +92,7 @@
       folder_search_policy_(folder_search_policy) {
   // INCLUDE_DOT_DOT must not be specified if recursive.
   DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
-  SbMemorySet(&find_data_, 0, sizeof(find_data_));
+  memset(&find_data_, 0, sizeof(find_data_));
   pending_paths_.push(root_path);
 }
 
@@ -107,7 +107,7 @@
     return FileInfo();
   }
   FileInfo ret;
-  SbMemoryCopy(&ret.find_data_, &find_data_, sizeof(find_data_));
+  memcpy(&ret.find_data_, &find_data_, sizeof(find_data_));
   return ret;
 }
 
diff --git a/src/base/files/file_path.cc b/src/base/files/file_path.cc
index 9c224b0..043d144 100644
--- a/src/base/files/file_path.cc
+++ b/src/base/files/file_path.cc
@@ -1238,7 +1238,7 @@
                                                           length);
     if (success) {
       // Reduce result.length() to actual string length.
-      result.resize(SbStringGetLength(result.c_str()));
+      result.resize(strlen(result.c_str()));
     } else {
       // An error occurred -> clear result.
       result.clear();
diff --git a/src/base/files/file_proxy.cc b/src/base/files/file_proxy.cc
index 6e0574f..a6ff4bd 100644
--- a/src/base/files/file_proxy.cc
+++ b/src/base/files/file_proxy.cc
@@ -209,7 +209,7 @@
         buffer_(new char[bytes_to_write]),
         bytes_to_write_(bytes_to_write),
         bytes_written_(0) {
-    SbMemoryCopy(buffer_.get(), buffer, bytes_to_write);
+    memcpy(buffer_.get(), buffer, bytes_to_write);
   }
 
   void RunWork(int64_t offset) {
diff --git a/src/base/files/file_proxy_unittest.cc b/src/base/files/file_proxy_unittest.cc
index 57b6b46..4e4e932 100644
--- a/src/base/files/file_proxy_unittest.cc
+++ b/src/base/files/file_proxy_unittest.cc
@@ -65,7 +65,7 @@
                int bytes_read) {
     error_ = error;
     buffer_.resize(bytes_read);
-    SbMemoryCopy(&buffer_[0], data, bytes_read);
+    memcpy(&buffer_[0], data, bytes_read);
     RunLoop::QuitCurrentWhenIdleDeprecated();
   }
 
diff --git a/src/base/files/file_util.cc b/src/base/files/file_util.cc
index d8e445a..8654654 100644
--- a/src/base/files/file_util.cc
+++ b/src/base/files/file_util.cc
@@ -77,8 +77,8 @@
     return false;
   }
 
-  return SbMemoryCompare(file1_content.get(), file2_content.get(),
-                         file1_length) == 0;
+  return memcmp(file1_content.get(), file2_content.get(),
+                file1_length) == 0;
 #else
   std::ifstream file1(filename1.value().c_str(),
                       std::ios::in | std::ios::binary);
diff --git a/src/base/files/file_util_unittest.cc b/src/base/files/file_util_unittest.cc
index 58828db..44570e2 100644
--- a/src/base/files/file_util_unittest.cc
+++ b/src/base/files/file_util_unittest.cc
@@ -130,7 +130,7 @@
   REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
 
   data->ReparseTag = 0xa0000003;
-  SbMemoryCopy(data->MountPointReparseBuffer.PathBuffer, target,
+  memcpy(data->MountPointReparseBuffer.PathBuffer, target,
                size_target + 2);
 
   data->MountPointReparseBuffer.SubstituteNameLength = size_target;
@@ -2843,8 +2843,8 @@
           .Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
 
   // Create test file.
-  ASSERT_EQ(static_cast<int>(SbStringGetLength(kTestData)),
-            WriteFile(file_path, kTestData, SbStringGetLength(kTestData)));
+  ASSERT_EQ(static_cast<int>(strlen(kTestData)),
+            WriteFile(file_path, kTestData, strlen(kTestData)));
 
   EXPECT_TRUE(ReadFileToString(file_path, &data));
   EXPECT_EQ(kTestData, data);
@@ -2926,14 +2926,14 @@
   int fd = open(pipe_path.value().c_str(), O_WRONLY);
   CHECK_NE(-1, fd);
   size_t written = 0;
-  while (written < SbStringGetLength(kTestData)) {
+  while (written < strlen(kTestData)) {
     ssize_t res =
-        write(fd, kTestData + written, SbStringGetLength(kTestData) - written);
+        write(fd, kTestData + written, strlen(kTestData) - written);
     if (res == -1)
       break;
     written += res;
   }
-  CHECK_EQ(SbStringGetLength(kTestData), written);
+  CHECK_EQ(strlen(kTestData), written);
   CHECK_EQ(0, close(fd));
   return 0;
 }
@@ -3091,8 +3091,8 @@
 
   DWORD written;
   EXPECT_TRUE(
-      ::WriteFile(ph, kTestData, SbStringGetLength(kTestData), &written, NULL));
-  EXPECT_EQ(SbStringGetLength(kTestData), written);
+      ::WriteFile(ph, kTestData, strlen(kTestData), &written, NULL));
+  EXPECT_EQ(strlen(kTestData), written);
   CloseHandle(ph);
   return 0;
 }
diff --git a/src/base/files/memory_mapped_file_unittest.cc b/src/base/files/memory_mapped_file_unittest.cc
index 0295994..33a39e4 100644
--- a/src/base/files/memory_mapped_file_unittest.cc
+++ b/src/base/files/memory_mapped_file_unittest.cc
@@ -28,7 +28,7 @@
 // Check that the watermark sequence is consistent with the |offset| provided.
 bool CheckBufferContents(const uint8_t* data, size_t size, size_t offset) {
   std::unique_ptr<uint8_t[]> test_data(CreateTestBuffer(size, offset));
-  return SbMemoryCompare(test_data.get(), data, size) == 0;
+  return memcmp(test_data.get(), data, size) == 0;
 }
 
 class MemoryMappedFileTest : public PlatformTest {
diff --git a/src/base/hash_unittest.cc b/src/base/hash_unittest.cc
index cc8a2ca..cb2897d 100644
--- a/src/base/hash_unittest.cc
+++ b/src/base/hash_unittest.cc
@@ -68,16 +68,16 @@
   const char* str;
   // Empty string (should hash to 0).
   str = "";
-  EXPECT_EQ(0u, Hash(str, SbStringGetLength(str)));
+  EXPECT_EQ(0u, Hash(str, strlen(str)));
 
   // Simple test.
   str = "hello world";
-  EXPECT_EQ(2794219650u, Hash(str, SbStringGetLength(str)));
+  EXPECT_EQ(2794219650u, Hash(str, strlen(str)));
 
   // Ensure that it stops reading after the given length, and does not expect a
   // null byte.
   str = "hello world; don't read this part";
-  EXPECT_EQ(2794219650u, Hash(str, SbStringGetLength("hello world")));
+  EXPECT_EQ(2794219650u, Hash(str, strlen("hello world")));
 }
 
 }  // namespace base
diff --git a/src/base/i18n/streaming_utf8_validator_unittest.cc b/src/base/i18n/streaming_utf8_validator_unittest.cc
index 2c8023d..c115cee 100644
--- a/src/base/i18n/streaming_utf8_validator_unittest.cc
+++ b/src/base/i18n/streaming_utf8_validator_unittest.cc
@@ -77,7 +77,7 @@
   // whether it is valid UTF-8 or not.
   void TestNumber(uint32_t n) const {
     char test[sizeof n];
-    SbMemoryCopy(test, &n, sizeof n);
+    memcpy(test, &n, sizeof n);
     StreamingUtf8Validator validator;
     EXPECT_EQ(IsStringUtf8(test, sizeof n),
               validator.AddBytes(test, sizeof n) == VALID_ENDPOINT)
@@ -214,10 +214,10 @@
 
   void Advance() {
     if (index_ < arraysize(valid) &&
-        prefix_length_ < SbStringGetLength(valid[index_]))
+        prefix_length_ < strlen(valid[index_]))
       ++prefix_length_;
     while (index_ < arraysize(valid) &&
-           prefix_length_ == SbStringGetLength(valid[index_])) {
+           prefix_length_ == strlen(valid[index_])) {
       ++index_;
       prefix_length_ = 1;
     }
@@ -309,7 +309,7 @@
 TEST(StreamingUtf8ValidatorTest, HelloWorld) {
   static const char kHelloWorld[] = "Hello, World!";
   EXPECT_EQ(VALID_ENDPOINT, StreamingUtf8Validator().AddBytes(
-                                kHelloWorld, SbStringGetLength(kHelloWorld)));
+                                kHelloWorld, strlen(kHelloWorld)));
 }
 
 // Check that the Reset() method works.
diff --git a/src/base/json/json_correctness_fuzzer.cc b/src/base/json/json_correctness_fuzzer.cc
index 935dbdf..c7d6d6f 100644
--- a/src/base/json/json_correctness_fuzzer.cc
+++ b/src/base/json/json_correctness_fuzzer.cc
@@ -29,7 +29,7 @@
   // Create a copy of input buffer, as otherwise we don't catch
   // overflow that touches the last byte (which is used in options).
   std::unique_ptr<char[]> input(new char[size - 1]);
-  SbMemoryCopy(input.get(), data, size - 1);
+  memcpy(input.get(), data, size - 1);
 
   base::StringPiece input_string(input.get(), size - 1);
 
diff --git a/src/base/json/json_parser_unittest.cc b/src/base/json/json_parser_unittest.cc
index f0e8573..0e5e10c 100644
--- a/src/base/json/json_parser_unittest.cc
+++ b/src/base/json/json_parser_unittest.cc
@@ -34,9 +34,9 @@
   // owned by |owner|, returning a StringPiece to |owner|.
   StringPiece MakeNotNullTerminatedInput(const char* input,
                                          std::unique_ptr<char[]>* owner) {
-    size_t str_len = SbStringGetLength(input);
+    size_t str_len = strlen(input);
     owner->reset(new char[str_len]);
-    SbMemoryCopy(owner->get(), input, str_len);
+    memcpy(owner->get(), input, str_len);
     return StringPiece(owner->get(), str_len);
   }
 
diff --git a/src/base/json/json_reader_fuzzer.cc b/src/base/json/json_reader_fuzzer.cc
index 1f2d049..2642646 100644
--- a/src/base/json/json_reader_fuzzer.cc
+++ b/src/base/json/json_reader_fuzzer.cc
@@ -14,7 +14,7 @@
   // Create a copy of input buffer, as otherwise we don't catch
   // overflow that touches the last byte (which is used in options).
   std::unique_ptr<char[]> input(new char[size - 1]);
-  SbMemoryCopy(input.get(), data, size - 1);
+  memcpy(input.get(), data, size - 1);
 
   base::StringPiece input_string(input.get(), size - 1);
 
diff --git a/src/base/json/json_value_serializer_unittest.cc b/src/base/json/json_value_serializer_unittest.cc
index 399bbd4..b12e5e7 100644
--- a/src/base/json/json_value_serializer_unittest.cc
+++ b/src/base/json/json_value_serializer_unittest.cc
@@ -151,8 +151,8 @@
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
   // Write it down in the file.
   FilePath temp_file(tempdir.GetPath().AppendASCII("test.json"));
-  ASSERT_EQ(static_cast<int>(SbStringGetLength(kProperJSON)),
-            WriteFile(temp_file, kProperJSON, SbStringGetLength(kProperJSON)));
+  ASSERT_EQ(static_cast<int>(strlen(kProperJSON)),
+            WriteFile(temp_file, kProperJSON, strlen(kProperJSON)));
 
   // Try to deserialize it through the serializer.
   JSONFileValueDeserializer file_deserializer(temp_file);
@@ -175,9 +175,9 @@
   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
   // Write it down in the file.
   FilePath temp_file(tempdir.GetPath().AppendASCII("test.json"));
-  ASSERT_EQ(static_cast<int>(SbStringGetLength(kProperJSONWithCommas)),
+  ASSERT_EQ(static_cast<int>(strlen(kProperJSONWithCommas)),
             WriteFile(temp_file, kProperJSONWithCommas,
-                      SbStringGetLength(kProperJSONWithCommas)));
+                      strlen(kProperJSONWithCommas)));
 
   // Try to deserialize it through the serializer.
   JSONFileValueDeserializer file_deserializer(temp_file);
diff --git a/src/base/json/string_escape_fuzzer.cc b/src/base/json/string_escape_fuzzer.cc
index 072f5ee..3cd8509 100644
--- a/src/base/json/string_escape_fuzzer.cc
+++ b/src/base/json/string_escape_fuzzer.cc
@@ -19,7 +19,7 @@
   // overflow that touches the last byte (which is used in put_in_quotes).
   size_t actual_size_char8 = size - 1;
   std::unique_ptr<char[]> input(new char[actual_size_char8]);
-  SbMemoryCopy(input.get(), data, actual_size_char8);
+  memcpy(input.get(), data, actual_size_char8);
 
   base::StringPiece input_string(input.get(), actual_size_char8);
   std::string escaped_string;
diff --git a/src/base/linux_util.cc b/src/base/linux_util.cc
index 3b2701e..60a42df 100644
--- a/src/base/linux_util.cc
+++ b/src/base/linux_util.cc
@@ -139,8 +139,8 @@
   if (output.length() > 0) {
     // lsb_release -d should return: Description:<tab>Distro Info
     const char field[] = "Description:\t";
-    if (output.compare(0, SbStringGetLength(field), field) == 0) {
-      SetLinuxDistro(output.substr(SbStringGetLength(field)));
+    if (output.compare(0, strlen(field), field) == 0) {
+      SetLinuxDistro(output.substr(strlen(field)));
     }
   }
   distro_state_singleton->CheckFinished();
diff --git a/src/base/logging.cc b/src/base/logging.cc
index c89ed7f..ee5704a 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -1203,13 +1203,13 @@
   if (level >= g_min_log_level && message) {
 #if defined(STARBOARD)
     SbLogRaw(message);
-    const size_t message_len = SbStringGetLength(message);
+    const size_t message_len = strlen(message);
     if (message_len > 0 && message[message_len - 1] != '\n') {
       SbLogRaw("\n");
     }
 #else
     size_t bytes_written = 0;
-    const size_t message_len = SbStringGetLength(message);
+    const size_t message_len = strlen(message);
     int rv;
     while (bytes_written < message_len) {
       rv = HANDLE_EINTR(
diff --git a/src/base/logging_win.cc b/src/base/logging_win.cc
index 152713a..1334ac3 100644
--- a/src/base/logging_win.cc
+++ b/src/base/logging_win.cc
@@ -83,7 +83,7 @@
     // The line.
     event.SetField(2, sizeof(line), &line);
     // The file.
-    event.SetField(3, SbStringGetLength(file) + 1, file);
+    event.SetField(3, strlen(file) + 1, file);
     // And finally the message.
     event.SetField(4, message.length() + 1 - message_start,
         message.c_str() + message_start);
diff --git a/src/base/md5.cc b/src/base/md5.cc
index 143a03f..bd91416 100644
--- a/src/base/md5.cc
+++ b/src/base/md5.cc
@@ -190,10 +190,10 @@
 
     t = 64 - t;
     if (len < t) {
-      SbMemoryCopy(p, buf, len);
+      memcpy(p, buf, len);
       return;
     }
-    SbMemoryCopy(p, buf, t);
+    memcpy(p, buf, t);
     byteReverse(ctx->in, 16);
     MD5Transform(ctx->buf, reinterpret_cast<uint32_t*>(ctx->in));
     buf += t;
@@ -203,7 +203,7 @@
   /* Process data in 64-byte chunks */
 
   while (len >= 64) {
-    SbMemoryCopy(ctx->in, buf, 64);
+    memcpy(ctx->in, buf, 64);
     byteReverse(ctx->in, 16);
     MD5Transform(ctx->buf, reinterpret_cast<uint32_t*>(ctx->in));
     buf += 64;
@@ -212,7 +212,7 @@
 
   /* Handle any remaining bytes of data. */
 
-  SbMemoryCopy(ctx->in, buf, len);
+  memcpy(ctx->in, buf, len);
 }
 
 /*
@@ -238,35 +238,35 @@
   /* Pad out to 56 mod 64 */
   if (count < 8) {
     /* Two lots of padding:  Pad the first block to 64 bytes */
-    SbMemorySet(p, 0, count);
+    memset(p, 0, count);
     byteReverse(ctx->in, 16);
     MD5Transform(ctx->buf, reinterpret_cast<uint32_t*>(ctx->in));
 
     /* Now fill the next block with 56 bytes */
-    SbMemorySet(ctx->in, 0, 56);
+    memset(ctx->in, 0, 56);
   } else {
     /* Pad block to 56 bytes */
-    SbMemorySet(p, 0, count - 8);
+    memset(p, 0, count - 8);
   }
   byteReverse(ctx->in, 14);
 
   /* Append length in bits and transform */
-  SbMemoryCopy(&ctx->in[14 * sizeof(ctx->bits[0])], &ctx->bits[0],
+  memcpy(&ctx->in[14 * sizeof(ctx->bits[0])], &ctx->bits[0],
                sizeof(ctx->bits[0]));
-  SbMemoryCopy(&ctx->in[15 * sizeof(ctx->bits[1])], &ctx->bits[1],
+  memcpy(&ctx->in[15 * sizeof(ctx->bits[1])], &ctx->bits[1],
                sizeof(ctx->bits[1]));
 
   MD5Transform(ctx->buf, reinterpret_cast<uint32_t*>(ctx->in));
   byteReverse(reinterpret_cast<uint8_t*>(ctx->buf), 4);
-  SbMemoryCopy(digest->a, ctx->buf, 16);
-  SbMemorySet(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+  memcpy(digest->a, ctx->buf, 16);
+  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
 }
 
 void MD5IntermediateFinal(MD5Digest* digest, const MD5Context* context) {
   /* MD5Final mutates the MD5Context*. Make a copy for generating the
      intermediate value. */
   MD5Context context_copy;
-  SbMemoryCopy(&context_copy, context, sizeof(context_copy));
+  memcpy(&context_copy, context, sizeof(context_copy));
   MD5Final(digest, &context_copy);
 }
 
diff --git a/src/base/md5_unittest.cc b/src/base/md5_unittest.cc
index 841d7d6..8df9d65 100644
--- a/src/base/md5_unittest.cc
+++ b/src/base/md5_unittest.cc
@@ -39,7 +39,7 @@
   MD5Digest digest;
   const char data[] = "";
 
-  MD5Sum(data, SbStringGetLength(data), &digest);
+  MD5Sum(data, strlen(data), &digest);
 
   int expected[] = {
     0xd4, 0x1d, 0x8c, 0xd9,
@@ -56,7 +56,7 @@
   MD5Digest digest;
   const char data[] = "a";
 
-  MD5Sum(data, SbStringGetLength(data), &digest);
+  MD5Sum(data, strlen(data), &digest);
 
   int expected[] = {
     0x0c, 0xc1, 0x75, 0xb9,
@@ -247,10 +247,10 @@
 
   // The header and full digest pairs are the same, and they aren't the same as
   // each other.
-  EXPECT_TRUE(!SbMemoryCompare(&header_digest, &check_header_digest,
+  EXPECT_TRUE(!memcmp(&header_digest, &check_header_digest,
                                sizeof(header_digest)));
-  EXPECT_TRUE(!SbMemoryCompare(&digest, &check_full_digest, sizeof(digest)));
-  EXPECT_TRUE(SbMemoryCompare(&digest, &header_digest, sizeof(digest)));
+  EXPECT_TRUE(!memcmp(&digest, &check_full_digest, sizeof(digest)));
+  EXPECT_TRUE(memcmp(&digest, &header_digest, sizeof(digest)));
 }
 
 }  // namespace base
diff --git a/src/base/memory/discardable_shared_memory_unittest.cc b/src/base/memory/discardable_shared_memory_unittest.cc
index 805477e..6320be7 100644
--- a/src/base/memory/discardable_shared_memory_unittest.cc
+++ b/src/base/memory/discardable_shared_memory_unittest.cc
@@ -409,7 +409,7 @@
   ASSERT_TRUE(rv);
 
   // Initialize all memory to '0xaa'.
-  SbMemorySet(memory2.memory(), 0xaa, kDataSize);
+  memset(memory2.memory(), 0xaa, kDataSize);
 
   // Unlock memory.
   memory2.SetNow(Time::FromDoubleT(1));
@@ -425,7 +425,7 @@
   // Check that reading memory after it has been purged is returning
   // zero-filled pages.
   uint8_t expected_data[kDataSize] = {};
-  EXPECT_EQ(SbMemoryCompare(memory2.memory(), expected_data, kDataSize), 0);
+  EXPECT_EQ(memcmp(memory2.memory(), expected_data, kDataSize), 0);
 }
 #endif
 
diff --git a/src/base/memory/ptr_util.h b/src/base/memory/ptr_util.h
index 0f61dd7..42f4f49 100644
--- a/src/base/memory/ptr_util.h
+++ b/src/base/memory/ptr_util.h
@@ -8,8 +8,6 @@
 #include <memory>
 #include <utility>
 
-#include "nb/cpp14oncpp11.h"
-
 namespace base {
 
 // Helper to transfer ownership of a raw pointer to a std::unique_ptr<T>.
diff --git a/src/base/memory/ref_counted.h b/src/base/memory/ref_counted.h
index c19072a..d4d71f8 100644
--- a/src/base/memory/ref_counted.h
+++ b/src/base/memory/ref_counted.h
@@ -153,7 +153,7 @@
 
  protected:
   explicit constexpr RefCountedThreadSafeBase(StartRefCountFromZeroTag) {}
-  explicit CONSTEXPR RefCountedThreadSafeBase(StartRefCountFromOneTag)
+  explicit constexpr RefCountedThreadSafeBase(StartRefCountFromOneTag)
       : ref_count_(1) {
 #if DCHECK_IS_ON()
     needs_adopt_ref_ = true;
diff --git a/src/base/memory/ref_counted_memory.cc b/src/base/memory/ref_counted_memory.cc
index 9239ffc..c3058a1 100644
--- a/src/base/memory/ref_counted_memory.cc
+++ b/src/base/memory/ref_counted_memory.cc
@@ -15,7 +15,7 @@
 bool RefCountedMemory::Equals(
     const scoped_refptr<RefCountedMemory>& other) const {
   return other.get() && size() == other->size() &&
-         (SbMemoryCompare(front(), other->front(), size()) == 0);
+         (memcmp(front(), other->front(), size()) == 0);
 }
 
 RefCountedMemory::RefCountedMemory() = default;
diff --git a/src/base/memory/ref_counted_memory_unittest.cc b/src/base/memory/ref_counted_memory_unittest.cc
index 3f4eb09..62dc44a 100644
--- a/src/base/memory/ref_counted_memory_unittest.cc
+++ b/src/base/memory/ref_counted_memory_unittest.cc
@@ -78,7 +78,7 @@
   static const char kData[] = "shm_dummy_data";
   auto shm = std::make_unique<SharedMemory>();
   ASSERT_TRUE(shm->CreateAndMapAnonymous(sizeof(kData)));
-  SbMemoryCopy(shm->memory(), kData, sizeof(kData));
+  memcpy(shm->memory(), kData, sizeof(kData));
 
   auto mem =
       MakeRefCounted<RefCountedSharedMemory>(std::move(shm), sizeof(kData));
@@ -97,7 +97,7 @@
     ReadOnlySharedMemoryMapping ro_mapping = region.region.Map();
     WritableSharedMemoryMapping rw_mapping = std::move(region.mapping);
     ASSERT_TRUE(rw_mapping.IsValid());
-    SbMemoryCopy(rw_mapping.memory(), kData, sizeof(kData));
+    memcpy(rw_mapping.memory(), kData, sizeof(kData));
     mem = MakeRefCounted<RefCountedSharedMemoryMapping>(std::move(ro_mapping));
   }
 
@@ -111,7 +111,7 @@
         ReadOnlySharedMemoryRegion::Create(sizeof(kData));
     WritableSharedMemoryMapping rw_mapping = std::move(region.mapping);
     ASSERT_TRUE(rw_mapping.IsValid());
-    SbMemoryCopy(rw_mapping.memory(), kData, sizeof(kData));
+    memcpy(rw_mapping.memory(), kData, sizeof(kData));
     mem = RefCountedSharedMemoryMapping::CreateFromWholeRegion(region.region);
   }
 
diff --git a/src/base/memory/scoped_refptr.h b/src/base/memory/scoped_refptr.h
index 1810b74..27b48a1 100644
--- a/src/base/memory/scoped_refptr.h
+++ b/src/base/memory/scoped_refptr.h
@@ -12,7 +12,6 @@
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 template <class T>
@@ -171,7 +170,7 @@
   constexpr scoped_refptr() = default;
 
   // Constructs from raw pointer. constexpr if |p| is null.
-  CONSTEXPR scoped_refptr(T* p) : ptr_(p) {
+  constexpr scoped_refptr(T* p) : ptr_(p) {
     if (ptr_)
       AddRef(ptr_);
   }
diff --git a/src/base/memory/shared_memory_helper.cc b/src/base/memory/shared_memory_helper.cc
index ea1326b..25a3059 100644
--- a/src/base/memory/shared_memory_helper.cc
+++ b/src/base/memory/shared_memory_helper.cc
@@ -131,11 +131,11 @@
 
       // Put a marker at the start of our data so we can confirm where it
       // begins.
-      crash_ptr = SbStringCopy(crash_ptr, kFileDataMarker,
+      crash_ptr = strncpy(crash_ptr, kFileDataMarker,
                                SbStringGetLength(kFileDataMarker));
       for (int i = original_fd_limit; i >= 0; --i) {
-        SbMemorySet(buf, 0, arraysize(buf));
-        SbMemorySet(fd_path, 0, arraysize(fd_path));
+        memset(buf, 0, arraysize(buf));
+        memset(fd_path, 0, arraysize(fd_path));
         snprintf(fd_path, arraysize(fd_path) - 1, "/proc/self/fd/%d", i);
         ssize_t count = readlink(fd_path, buf, arraysize(buf) - 1);
         if (count < 0) {
@@ -144,7 +144,7 @@
         }
 
         if (crash_ptr + count + 1 < crash_buffer + arraysize(crash_buffer)) {
-          crash_ptr = SbStringCopy(crash_ptr, buf, count + 1);
+          crash_ptr = strncpy(crash_ptr, buf, count + 1);
         }
         LOG(ERROR) << i << ": " << buf;
       }
diff --git a/src/base/memory/shared_memory_mac_unittest.cc b/src/base/memory/shared_memory_mac_unittest.cc
index 0b78455..c476368 100644
--- a/src/base/memory/shared_memory_mac_unittest.cc
+++ b/src/base/memory/shared_memory_mac_unittest.cc
@@ -63,7 +63,7 @@
   }
   std::unique_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false));
   shared_memory->Map(size);
-  SbMemorySet(shared_memory->memory(), 'a', size);
+  memset(shared_memory->memory(), 'a', size);
   return shared_memory;
 }
 
@@ -270,9 +270,9 @@
 
   size_t page_size = SysInfo::VMAllocationGranularity();
   char* start = static_cast<char*>(shared_memory.memory());
-  SbMemorySet(start, 'a', page_size);
-  SbMemorySet(start + page_size, 'b', page_size);
-  SbMemorySet(start + 2 * page_size, 'c', page_size);
+  memset(start, 'a', page_size);
+  memset(start + page_size, 'b', page_size);
+  memset(start + 2 * page_size, 'c', page_size);
 
   // Send the underlying memory object to the client process.
   SendMachPort(
@@ -371,7 +371,7 @@
   ASSERT_TRUE(shm2.IsValid());
   SharedMemory shared_memory2(shm2, true);
   shared_memory2.Map(s_memory_size);
-  ASSERT_DEATH(SbMemorySet(shared_memory2.memory(), 'b', s_memory_size), "");
+  ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), "");
 }
 
 // Tests that duplication of the underlying handle works.
@@ -387,8 +387,8 @@
     SharedMemory shared_memory2(shm2, true);
     shared_memory2.Map(s_memory_size);
 
-    ASSERT_EQ(0, SbMemoryCompare(shared_memory->memory(),
-                                 shared_memory2.memory(), s_memory_size));
+    ASSERT_EQ(0, memcmp(shared_memory->memory(),
+                        shared_memory2.memory(), s_memory_size));
   }
 
   EXPECT_EQ(active_name_count, GetActiveNameCount());
@@ -432,7 +432,7 @@
 
   // The memory should still be readonly, since the underlying memory object
   // is readonly.
-  ASSERT_DEATH(SbMemorySet(shared_memory2.memory(), 'b', s_memory_size), "");
+  ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), "");
 }
 
 // Tests that the method GetReadOnlyHandle() doesn't leak.
diff --git a/src/base/memory/shared_memory_region_unittest.cc b/src/base/memory/shared_memory_region_unittest.cc
index d80affe..1098360 100644
--- a/src/base/memory/shared_memory_region_unittest.cc
+++ b/src/base/memory/shared_memory_region_unittest.cc
@@ -38,7 +38,7 @@
         CreateMappedRegion<SharedMemoryRegionType>(kRegionSize);
     ASSERT_TRUE(region_.IsValid());
     ASSERT_TRUE(rw_mapping_.IsValid());
-    SbMemorySet(rw_mapping_.memory(), 'G', kRegionSize);
+    memset(rw_mapping_.memory(), 'G', kRegionSize);
     EXPECT_TRUE(IsMemoryFilledWithByte(rw_mapping_.memory(), kRegionSize, 'G'));
   }
 
@@ -70,14 +70,14 @@
   typename TypeParam::MappingType mapping = moved_region.Map();
   ASSERT_TRUE(mapping.IsValid());
   EXPECT_NE(this->rw_mapping_.memory(), mapping.memory());
-  EXPECT_EQ(SbMemoryCompare(this->rw_mapping_.memory(), mapping.memory(),
-                            kRegionSize),
+  EXPECT_EQ(memcmp(this->rw_mapping_.memory(), mapping.memory(),
+                   kRegionSize),
             0);
 
   // Verify that the second mapping reflects changes in the first.
-  SbMemorySet(this->rw_mapping_.memory(), '#', kRegionSize);
-  EXPECT_EQ(SbMemoryCompare(this->rw_mapping_.memory(), mapping.memory(),
-                            kRegionSize),
+  memset(this->rw_mapping_.memory(), '#', kRegionSize);
+  EXPECT_EQ(memcmp(this->rw_mapping_.memory(), mapping.memory(),
+                   kRegionSize),
             0);
 }
 
@@ -95,14 +95,14 @@
   typename TypeParam::MappingType mapping = this->region_.Map();
   ASSERT_TRUE(mapping.IsValid());
   EXPECT_NE(this->rw_mapping_.memory(), mapping.memory());
-  EXPECT_EQ(SbMemoryCompare(this->rw_mapping_.memory(), mapping.memory(),
-                            kRegionSize),
+  EXPECT_EQ(memcmp(this->rw_mapping_.memory(), mapping.memory(),
+                   kRegionSize),
             0);
 
   // Verify that the second mapping reflects changes in the first.
-  SbMemorySet(this->rw_mapping_.memory(), '#', kRegionSize);
-  EXPECT_EQ(SbMemoryCompare(this->rw_mapping_.memory(), mapping.memory(),
-                            kRegionSize),
+  memset(this->rw_mapping_.memory(), '#', kRegionSize);
+  EXPECT_EQ(memcmp(this->rw_mapping_.memory(), mapping.memory(),
+                   kRegionSize),
             0);
 
   // Close the region and unmap the first memory segment, verify the second
@@ -132,7 +132,7 @@
   EXPECT_TRUE(IsMemoryFilledWithByte(mapping.memory(), kRegionSize, 'G'));
 
   // Verify that the second mapping reflects changes in the first.
-  SbMemorySet(this->rw_mapping_.memory(), '#', kRegionSize);
+  memset(this->rw_mapping_.memory(), '#', kRegionSize);
   EXPECT_EQ(SbMemoryCompare(this->rw_mapping_.memory(), mapping.memory(),
                             kRegionSize),
             0);
@@ -276,7 +276,7 @@
   ReadOnlySharedMemoryMapping mapping = region.Map();
   ASSERT_TRUE(mapping.IsValid());
   void* memory_ptr = const_cast<void*>(mapping.memory());
-  EXPECT_DEATH_IF_SUPPORTED(SbMemorySet(memory_ptr, 'G', kRegionSize), "");
+  EXPECT_DEATH_IF_SUPPORTED(memset(memory_ptr, 'G', kRegionSize), "");
 }
 
 TEST_F(ReadOnlySharedMemoryRegionTest,
@@ -286,7 +286,7 @@
   ReadOnlySharedMemoryMapping mapping = region.Map();
   ASSERT_TRUE(mapping.IsValid());
   void* memory_ptr = const_cast<void*>(mapping.memory());
-  EXPECT_DEATH_IF_SUPPORTED(SbMemorySet(memory_ptr, 'G', kRegionSize), "");
+  EXPECT_DEATH_IF_SUPPORTED(memset(memory_ptr, 'G', kRegionSize), "");
 }
 
 class UnsafeSharedMemoryRegionTest : public ::testing::Test {};
diff --git a/src/base/memory/shared_memory_unittest.cc b/src/base/memory/shared_memory_unittest.cc
index 1e97c93..676feb6 100644
--- a/src/base/memory/shared_memory_unittest.cc
+++ b/src/base/memory/shared_memory_unittest.cc
@@ -167,8 +167,8 @@
   ASSERT_NE(memory2.memory(), static_cast<void*>(nullptr));
 
   // Write data to the first memory segment, verify contents of second.
-  SbMemorySet(memory1.memory(), '1', kDataSize);
-  EXPECT_EQ(SbMemoryCompare(memory1.memory(), memory2.memory(), kDataSize), 0);
+  memset(memory1.memory(), '1', kDataSize);
+  EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
 
   // Close the first memory segment, and verify the second has the right data.
   memory1.Close();
@@ -213,7 +213,7 @@
   EXPECT_LT(memory1.mapped_size(),
             kDataSize + SysInfo::VMAllocationGranularity());
 
-  SbMemorySet(memory1.memory(), 'G', kDataSize);
+  memset(memory1.memory(), 'G', kDataSize);
 
   SharedMemory memory2;
   // Should not be able to create if openExisting is false.
@@ -261,7 +261,7 @@
   ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
   char* ptr = static_cast<char*>(memory.memory());
   ASSERT_NE(ptr, static_cast<void*>(nullptr));
-  SbMemorySet(ptr, 'G', kDataSize);
+  memset(ptr, 'G', kDataSize);
 
   memory.Close();
 
@@ -374,7 +374,7 @@
 #endif
   ASSERT_TRUE(writable_shmem.Create(options));
   ASSERT_TRUE(writable_shmem.Map(options.size));
-  SbMemoryCopy(writable_shmem.memory(), contents.data(), contents.size());
+  memcpy(writable_shmem.memory(), contents.data(), contents.size());
   EXPECT_TRUE(writable_shmem.Unmap());
 
   SharedMemoryHandle readonly_handle = writable_shmem.GetReadOnlyHandle();
@@ -397,7 +397,7 @@
   // Make sure the writable instance is still writable.
   ASSERT_TRUE(writable_shmem.Map(contents.size()));
   StringPiece new_contents = "Goodbye";
-  SbMemoryCopy(writable_shmem.memory(), new_contents.data(),
+  memcpy(writable_shmem.memory(), new_contents.data(),
                new_contents.size());
   EXPECT_EQ(new_contents,
             StringPiece(static_cast<const char*>(writable_shmem.memory()),
@@ -476,7 +476,7 @@
 
   SharedMemory shmem;
   ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size()));
-  SbMemoryCopy(shmem.memory(), contents.data(), contents.size());
+  memcpy(shmem.memory(), contents.data(), contents.size());
   EXPECT_TRUE(shmem.Unmap());
 
   SharedMemoryHandle shared_handle = shmem.handle().Duplicate();
@@ -532,14 +532,14 @@
       shmem.requested_size());
 
   // |shmem| should be able to update the content.
-  SbMemoryCopy(shmem.memory(), kContents.data(), kContents.size());
+  memcpy(shmem.memory(), kContents.data(), kContents.size());
 
   ASSERT_EQ(kContents, shmem_contents);
   ASSERT_EQ(kContents, shared_contents);
   ASSERT_EQ(kContents, readonly_contents);
 
   // |shared| should also be able to update the content.
-  SbMemoryCopy(shared.memory(), ToLowerASCII(kContents).c_str(),
+  memcpy(shared.memory(), ToLowerASCII(kContents).c_str(),
                kContents.size());
 
   ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), shmem_contents);
diff --git a/src/base/memory/shared_memory_win_unittest.cc b/src/base/memory/shared_memory_win_unittest.cc
index 1763013..6c869ac 100644
--- a/src/base/memory/shared_memory_win_unittest.cc
+++ b/src/base/memory/shared_memory_win_unittest.cc
@@ -68,7 +68,7 @@
   // Read from parent pipe.
   const size_t buf_size = 1000;
   char buffer[buf_size];
-  SbMemorySet(buffer, 0, buf_size);
+  memset(buffer, 0, buf_size);
   DWORD bytes_read;
   BOOL success = ReadFile(pipe, buffer, buf_size, &bytes_read, NULL);
 
diff --git a/src/base/message_loop/message_loop_unittest.cc b/src/base/message_loop/message_loop_unittest.cc
index e9e68ac..f0e7709 100644
--- a/src/base/message_loop/message_loop_unittest.cc
+++ b/src/base/message_loop/message_loop_unittest.cc
@@ -460,7 +460,7 @@
 
 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
     : signal_(signal), wait_(wait) {
-  SbMemorySet(buffer_, 0, sizeof(buffer_));
+  memset(buffer_, 0, sizeof(buffer_));
 
   file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                        FILE_FLAG_OVERLAPPED, NULL));
diff --git a/src/base/message_loop/message_pump_win.cc b/src/base/message_loop/message_pump_win.cc
index 32413d6..5e60b30 100644
--- a/src/base/message_loop/message_pump_win.cc
+++ b/src/base/message_loop/message_pump_win.cc
@@ -443,7 +443,7 @@
 // MessagePumpForIO public:
 
 MessagePumpForIO::IOContext::IOContext() {
-  SbMemorySet(&overlapped, 0, sizeof(overlapped));
+  memset(&overlapped, 0, sizeof(overlapped));
 }
 
 MessagePumpForIO::MessagePumpForIO() {
@@ -576,7 +576,7 @@
 
 // Asks the OS for another IO completion result.
 bool MessagePumpForIO::GetIOItem(DWORD timeout, IOItem* item) {
-  SbMemorySet(item, 0, sizeof(*item));
+  memset(item, 0, sizeof(*item));
   ULONG_PTR key = reinterpret_cast<ULONG_PTR>(nullptr);
   OVERLAPPED* overlapped = nullptr;
   if (!GetQueuedCompletionStatus(port_.Get(), &item->bytes_transfered, &key,
diff --git a/src/base/metrics/field_trial.cc b/src/base/metrics/field_trial.cc
index f659c7b..3130afd 100644
--- a/src/base/metrics/field_trial.cc
+++ b/src/base/metrics/field_trial.cc
@@ -1158,7 +1158,7 @@
     // in memory, so we can avoid this memcpy.
     char* dst = reinterpret_cast<char*>(new_entry) +
                 sizeof(FieldTrial::FieldTrialEntry);
-    SbMemoryCopy(dst, pickle.data(), pickle.size());
+    memcpy(dst, pickle.data(), pickle.size());
 
     // Update the ref on the field trial and add it to the list to be made
     // iterable.
@@ -1458,7 +1458,7 @@
   // memory, so we can avoid this memcpy.
   char* dst =
       reinterpret_cast<char*>(entry) + sizeof(FieldTrial::FieldTrialEntry);
-  SbMemoryCopy(dst, pickle.data(), pickle.size());
+  memcpy(dst, pickle.data(), pickle.size());
 
   allocator->MakeIterable(ref);
   field_trial->ref_ = ref;
diff --git a/src/base/metrics/histogram_samples.cc b/src/base/metrics/histogram_samples.cc
index b8527c4..dffd703 100644
--- a/src/base/metrics/histogram_samples.cc
+++ b/src/base/metrics/histogram_samples.cc
@@ -173,7 +173,7 @@
 HistogramSamples::LocalMetadata::LocalMetadata() {
   // This is the same way it's done for persistent metadata since no ctor
   // is called for the data members in that case.
-  SbMemorySet(this, 0, sizeof(*this));
+  memset(this, 0, sizeof(*this));
 }
 
 HistogramSamples::HistogramSamples(uint64_t id, Metadata* meta)
diff --git a/src/base/metrics/metrics_hashes.cc b/src/base/metrics/metrics_hashes.cc
index 261f558..3f72311 100644
--- a/src/base/metrics/metrics_hashes.cc
+++ b/src/base/metrics/metrics_hashes.cc
@@ -17,7 +17,7 @@
 inline uint64_t DigestToUInt64(const base::MD5Digest& digest) {
   uint64_t value;
   DCHECK_GE(sizeof(digest.a), sizeof(value));
-  SbMemoryCopy(&value, digest.a, sizeof(value));
+  memcpy(&value, digest.a, sizeof(value));
   return base::NetToHost64(value);
 }
 
diff --git a/src/base/metrics/persistent_histogram_allocator.cc b/src/base/metrics/persistent_histogram_allocator.cc
index 478f3cd..669ca89 100644
--- a/src/base/metrics/persistent_histogram_allocator.cc
+++ b/src/base/metrics/persistent_histogram_allocator.cc
@@ -332,7 +332,7 @@
       memory_allocator_->New<PersistentHistogramData>(
           offsetof(PersistentHistogramData, name) + name.length() + 1);
   if (histogram_data) {
-    SbMemoryCopy(histogram_data->name, name.c_str(), name.size() + 1);
+    memcpy(histogram_data->name, name.c_str(), name.size() + 1);
     histogram_data->histogram_type = histogram_type;
     histogram_data->flags = flags | HistogramBase::kIsPersistent;
   }
diff --git a/src/base/metrics/persistent_histogram_allocator_unittest.cc b/src/base/metrics/persistent_histogram_allocator_unittest.cc
index c387eff..f8de3d5 100644
--- a/src/base/metrics/persistent_histogram_allocator_unittest.cc
+++ b/src/base/metrics/persistent_histogram_allocator_unittest.cc
@@ -34,7 +34,7 @@
     allocator_memory_.reset(new char[kAllocatorMemorySize]);
 
     GlobalHistogramAllocator::ReleaseForTesting();
-    SbMemorySet(allocator_memory_.get(), 0, kAllocatorMemorySize);
+    memset(allocator_memory_.get(), 0, kAllocatorMemorySize);
     GlobalHistogramAllocator::CreateWithPersistentMemory(
         allocator_memory_.get(), kAllocatorMemorySize, 0, 0,
         "PersistentHistogramAllocatorTest");
diff --git a/src/base/metrics/persistent_memory_allocator.cc b/src/base/metrics/persistent_memory_allocator.cc
index 52fd280..e30e10e 100644
--- a/src/base/metrics/persistent_memory_allocator.cc
+++ b/src/base/metrics/persistent_memory_allocator.cc
@@ -414,7 +414,7 @@
       shared_meta()->name = Allocate(name_length, 0);
       char* name_cstr = GetAsArray<char>(shared_meta()->name, 0, name_length);
       if (name_cstr)
-        SbMemoryCopy(name_cstr, name.data(), name.length());
+        memcpy(name_cstr, name.data(), name.length());
     }
 
     shared_meta()->memory_state.store(MEMORY_INITIALIZED,
@@ -997,7 +997,7 @@
   // added to the process now istead of only when first accessed).
   address = SbMemoryAllocate(size);
   DPCHECK(address);
-  SbMemorySet(address, 0, size);
+  memset(address, 0, size);
   return Memory(address, MEM_MALLOC);
 }
 
diff --git a/src/base/metrics/sample_vector_unittest.cc b/src/base/metrics/sample_vector_unittest.cc
index cf54e0c..1b1f51d 100644
--- a/src/base/metrics/sample_vector_unittest.cc
+++ b/src/base/metrics/sample_vector_unittest.cc
@@ -375,7 +375,7 @@
   std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
   samples_ref.store(0, std::memory_order_relaxed);
   HistogramSamples::Metadata samples_meta;
-  SbMemorySet(&samples_meta, 0, sizeof(samples_meta));
+  memset(&samples_meta, 0, sizeof(samples_meta));
 
   // Custom buckets: [1, 5) [5, 10)
   BucketRanges ranges(3);
@@ -468,7 +468,7 @@
   std::atomic<PersistentMemoryAllocator::Reference> samples_ref;
   samples_ref.store(0, std::memory_order_relaxed);
   HistogramSamples::Metadata samples_meta;
-  SbMemorySet(&samples_meta, 0, sizeof(samples_meta));
+  memset(&samples_meta, 0, sizeof(samples_meta));
 
   // Custom buckets: [1, 5) [5, 10)
   BucketRanges ranges(3);
diff --git a/src/base/numerics/checked_math.h b/src/base/numerics/checked_math.h
index 28b49b8..8b8e642 100644
--- a/src/base/numerics/checked_math.h
+++ b/src/base/numerics/checked_math.h
@@ -116,25 +116,25 @@
 
   // Prototypes for the supported arithmetic operator overloads.
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator+=(const Src rhs);
+  constexpr CheckedNumeric& operator+=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator-=(const Src rhs);
+  constexpr CheckedNumeric& operator-=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator*=(const Src rhs);
+  constexpr CheckedNumeric& operator*=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator/=(const Src rhs);
+  constexpr CheckedNumeric& operator/=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator%=(const Src rhs);
+  constexpr CheckedNumeric& operator%=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator<<=(const Src rhs);
+  constexpr CheckedNumeric& operator<<=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator>>=(const Src rhs);
+  constexpr CheckedNumeric& operator>>=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator&=(const Src rhs);
+  constexpr CheckedNumeric& operator&=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator|=(const Src rhs);
+  constexpr CheckedNumeric& operator|=(const Src rhs);
   template <typename Src>
-  CONSTEXPR CheckedNumeric& operator^=(const Src rhs);
+  constexpr CheckedNumeric& operator^=(const Src rhs);
 
   constexpr CheckedNumeric operator-() const {
     // The negation of two's complement int min is int min, so we simply
@@ -199,23 +199,23 @@
         SafeUnsignedAbs(state_.value()), state_.is_valid());
   }
 
-  CONSTEXPR CheckedNumeric& operator++() const {
+  constexpr CheckedNumeric& operator++() const {
     *this += 1;
     return *this;
   }
 
-  CONSTEXPR CheckedNumeric operator++(int) const {
+  constexpr CheckedNumeric operator++(int) const {
     CheckedNumeric value = *this;
     *this += 1;
     return value;
   }
 
-  CONSTEXPR CheckedNumeric& operator--() const {
+  constexpr CheckedNumeric& operator--() const {
     *this -= 1;
     return *this;
   }
 
-  CONSTEXPR CheckedNumeric operator--(int) const {
+  constexpr CheckedNumeric operator--(int) const {
     CheckedNumeric value = *this;
     *this -= 1;
     return value;
@@ -226,7 +226,7 @@
   template <template <typename, typename, typename> class M,
             typename L,
             typename R>
-  static CONSTEXPR CheckedNumeric MathOp(const L lhs, const R rhs) {
+  static constexpr CheckedNumeric MathOp(const L lhs, const R rhs) {
     using Math = typename MathWrapper<M, L, R>::math;
     T result = 0;
     bool is_valid =
@@ -237,7 +237,7 @@
 
   // Assignment arithmetic operations.
   template <template <typename, typename, typename> class M, typename R>
-  CONSTEXPR CheckedNumeric& MathOp(const R rhs) {
+  constexpr CheckedNumeric& MathOp(const R rhs) {
     using Math = typename MathWrapper<M, T, R>::math;
     T result = 0;  // Using T as the destination saves a range check.
     bool is_valid = state_.is_valid() && Wrapper<R>::is_valid(rhs) &&
diff --git a/src/base/numerics/checked_math_impl.h b/src/base/numerics/checked_math_impl.h
index a4562bd..47c5492 100644
--- a/src/base/numerics/checked_math_impl.h
+++ b/src/base/numerics/checked_math_impl.h
@@ -13,14 +13,13 @@
 
 #include "base/numerics/safe_conversions.h"
 #include "base/numerics/safe_math_shared_impl.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
 namespace internal {
 
 template <typename T>
-CONSTEXPR bool CheckedAddImpl(T x, T y, T* result) {
+constexpr bool CheckedAddImpl(T x, T y, T* result) {
   static_assert(std::is_integral<T>::value, "Type must be integral");
   // Since the value of x+y is undefined if we have a signed type, we compute
   // it using the unsigned type of the same size.
@@ -47,7 +46,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     // TODO(jschuh) Make this "constexpr if" once we're C++17.
     if (CheckedAddFastOp<T, U>::is_supported)
       return CheckedAddFastOp<T, U>::Do(x, y, result);
@@ -80,7 +79,7 @@
 };
 
 template <typename T>
-CONSTEXPR bool CheckedSubImpl(T x, T y, T* result) {
+constexpr bool CheckedSubImpl(T x, T y, T* result) {
   static_assert(std::is_integral<T>::value, "Type must be integral");
   // Since the value of x+y is undefined if we have a signed type, we compute
   // it using the unsigned type of the same size.
@@ -107,7 +106,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     // TODO(jschuh) Make this "constexpr if" once we're C++17.
     if (CheckedSubFastOp<T, U>::is_supported)
       return CheckedSubFastOp<T, U>::Do(x, y, result);
@@ -140,7 +139,7 @@
 };
 
 template <typename T>
-CONSTEXPR bool CheckedMulImpl(T x, T y, T* result) {
+constexpr bool CheckedMulImpl(T x, T y, T* result) {
   static_assert(std::is_integral<T>::value, "Type must be integral");
   // Since the value of x*y is potentially undefined if we have a signed type,
   // we compute it using the unsigned type of the same size.
@@ -169,7 +168,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     // TODO(jschuh) Make this "constexpr if" once we're C++17.
     if (CheckedMulFastOp<T, U>::is_supported)
       return CheckedMulFastOp<T, U>::Do(x, y, result);
@@ -210,7 +209,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     if (BASE_NUMERICS_UNLIKELY(!y))
       return false;
 
@@ -249,7 +248,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     using Promotion = typename BigEnoughPromotion<T, U>::type;
     if (BASE_NUMERICS_LIKELY(y)) {
       Promotion presult = static_cast<Promotion>(x) % static_cast<Promotion>(y);
@@ -273,7 +272,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = T;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U shift, V* result) {
+  static constexpr bool Do(T x, U shift, V* result) {
     // Disallow negative numbers and verify the shift is in bounds.
     if (BASE_NUMERICS_LIKELY(!IsValueNegative(x) &&
                              as_unsigned(shift) <
@@ -327,7 +326,7 @@
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     result_type tmp = static_cast<result_type>(x) & static_cast<result_type>(y);
     *result = static_cast<V>(tmp);
     return IsValueInRangeForNumericType<V>(tmp);
@@ -346,7 +345,7 @@
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     result_type tmp = static_cast<result_type>(x) | static_cast<result_type>(y);
     *result = static_cast<V>(tmp);
     return IsValueInRangeForNumericType<V>(tmp);
@@ -365,7 +364,7 @@
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     result_type tmp = static_cast<result_type>(x) ^ static_cast<result_type>(y);
     *result = static_cast<V>(tmp);
     return IsValueInRangeForNumericType<V>(tmp);
@@ -385,7 +384,7 @@
                             std::is_arithmetic<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     result_type tmp = IsGreater<T, U>::Test(x, y) ? static_cast<result_type>(x)
                                                   : static_cast<result_type>(y);
     *result = static_cast<V>(tmp);
@@ -406,7 +405,7 @@
                             std::is_arithmetic<U>::value>::type> {
   using result_type = typename LowestValuePromotion<T, U>::type;
   template <typename V>
-  static CONSTEXPR bool Do(T x, U y, V* result) {
+  static constexpr bool Do(T x, U y, V* result) {
     result_type tmp = IsLess<T, U>::Test(x, y) ? static_cast<result_type>(x)
                                                : static_cast<result_type>(y);
     *result = static_cast<V>(tmp);
@@ -424,7 +423,7 @@
                               std::is_floating_point<U>::value>::type> { \
     using result_type = typename MaxExponentPromotion<T, U>::type;       \
     template <typename V>                                                \
-    static CONSTEXPR bool Do(T x, U y, V* result) {                      \
+    static constexpr bool Do(T x, U y, V* result) {                      \
       using Promotion = typename MaxExponentPromotion<T, U>::type;       \
       Promotion presult = x OP y;                                        \
       *result = static_cast<V>(presult);                                 \
@@ -517,7 +516,7 @@
 
   // Ensures that a type conversion does not trigger undefined behavior.
   template <typename Src>
-  static CONSTEXPR T WellDefinedConversionOrNaN(const Src value,
+  static constexpr T WellDefinedConversionOrNaN(const Src value,
                                                 const bool is_valid) {
     using SrcType = typename internal::UnderlyingType<Src>::type;
     return (StaticDstRangeRelationToSrcRange<T, SrcType>::value ==
diff --git a/src/base/numerics/clamped_math.h b/src/base/numerics/clamped_math.h
index a1fc738..2c692a4 100644
--- a/src/base/numerics/clamped_math.h
+++ b/src/base/numerics/clamped_math.h
@@ -56,25 +56,25 @@
 
   // Prototypes for the supported arithmetic operator overloads.
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator+=(const Src rhs);
+  constexpr ClampedNumeric& operator+=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator-=(const Src rhs);
+  constexpr ClampedNumeric& operator-=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator*=(const Src rhs);
+  constexpr ClampedNumeric& operator*=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator/=(const Src rhs);
+  constexpr ClampedNumeric& operator/=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator%=(const Src rhs);
+  constexpr ClampedNumeric& operator%=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator<<=(const Src rhs);
+  constexpr ClampedNumeric& operator<<=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator>>=(const Src rhs);
+  constexpr ClampedNumeric& operator>>=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator&=(const Src rhs);
+  constexpr ClampedNumeric& operator&=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator|=(const Src rhs);
+  constexpr ClampedNumeric& operator|=(const Src rhs);
   template <typename Src>
-  CONSTEXPR ClampedNumeric& operator^=(const Src rhs);
+  constexpr ClampedNumeric& operator^=(const Src rhs);
 
   constexpr ClampedNumeric operator-() const {
     // The negation of two's complement int min is int min, so that's the
@@ -117,23 +117,23 @@
         SafeUnsignedAbs(value_));
   }
 
-  CONSTEXPR ClampedNumeric& operator++() const {
+  constexpr ClampedNumeric& operator++() const {
     *this += 1;
     return *this;
   }
 
-  CONSTEXPR ClampedNumeric operator++(int) const {
+  constexpr ClampedNumeric operator++(int) const {
     ClampedNumeric value = *this;
     *this += 1;
     return value;
   }
 
-  CONSTEXPR ClampedNumeric& operator--() const {
+  constexpr ClampedNumeric& operator--() const {
     *this -= 1;
     return *this;
   }
 
-  CONSTEXPR ClampedNumeric operator--(int) const {
+  constexpr ClampedNumeric operator--(int) const {
     ClampedNumeric value = *this;
     *this -= 1;
     return value;
@@ -152,7 +152,7 @@
 
   // Assignment arithmetic operations.
   template <template <typename, typename, typename> class M, typename R>
-  CONSTEXPR ClampedNumeric& MathOp(const R rhs) {
+  constexpr ClampedNumeric& MathOp(const R rhs) {
     using Math = typename MathWrapper<M, T, R>::math;
     *this =
         ClampedNumeric<T>(Math::template Do<T>(value_, Wrapper<R>::value(rhs)));
diff --git a/src/base/numerics/clamped_math_impl.h b/src/base/numerics/clamped_math_impl.h
index 271bc6e..1a7e234 100644
--- a/src/base/numerics/clamped_math_impl.h
+++ b/src/base/numerics/clamped_math_impl.h
@@ -76,7 +76,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U y) {
+  static constexpr V Do(T x, U y) {
     if (ClampedAddFastOp<T, U>::is_supported)
       return ClampedAddFastOp<T, U>::template Do<V>(x, y);
 
@@ -102,7 +102,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U y) {
+  static constexpr V Do(T x, U y) {
     // TODO(jschuh) Make this "constexpr if" once we're C++17.
     if (ClampedSubFastOp<T, U>::is_supported)
       return ClampedSubFastOp<T, U>::template Do<V>(x, y);
@@ -129,7 +129,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U y) {
+  static constexpr V Do(T x, U y) {
     // TODO(jschuh) Make this "constexpr if" once we're C++17.
     if (ClampedMulFastOp<T, U>::is_supported)
       return ClampedMulFastOp<T, U>::template Do<V>(x, y);
@@ -153,7 +153,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U y) {
+  static constexpr V Do(T x, U y) {
     V result = {};
     if (BASE_NUMERICS_LIKELY((CheckedDivOp<T, U>::Do(x, y, &result))))
       return result;
@@ -173,7 +173,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U y) {
+  static constexpr V Do(T x, U y) {
     V result = {};
     return BASE_NUMERICS_LIKELY((CheckedModOp<T, U>::Do(x, y, &result)))
                ? result
@@ -193,7 +193,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = T;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U shift) {
+  static constexpr V Do(T x, U shift) {
     static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
     if (BASE_NUMERICS_LIKELY(shift < std::numeric_limits<T>::digits)) {
       // Shift as unsigned to avoid undefined behavior.
@@ -217,7 +217,7 @@
                                             std::is_integral<U>::value>::type> {
   using result_type = T;
   template <typename V = result_type>
-  static CONSTEXPR V Do(T x, U shift) {
+  static constexpr V Do(T x, U shift) {
     static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
     // Signed right shift is odd, because it saturates to -1 or 0.
     const V saturated = as_unsigned(V(0)) - IsValueNegative(x);
diff --git a/src/base/numerics/safe_math_shared_impl.h b/src/base/numerics/safe_math_shared_impl.h
index 02d04ba..f7b1a94 100644
--- a/src/base/numerics/safe_math_shared_impl.h
+++ b/src/base/numerics/safe_math_shared_impl.h
@@ -13,7 +13,6 @@
 #include <type_traits>
 
 #include "base/numerics/safe_conversions.h"
-#include "nb/cpp14oncpp11.h"
 
 // Where available use builtin math overflow support on Clang and GCC.
 #if !defined(__native_client__) &&                         \
@@ -225,7 +224,7 @@
   /* Assignment arithmetic operator implementation from CLASS##Numeric. */     \
   template <typename L>                                                        \
   template <typename R>                                                        \
-  CONSTEXPR CLASS##Numeric<L>& CLASS##Numeric<L>::operator CMP_OP(             \
+  constexpr CLASS##Numeric<L>& CLASS##Numeric<L>::operator CMP_OP(             \
       const R rhs) {                                                           \
     return MathOp<CLASS##OP_NAME##Op>(rhs);                                    \
   }                                                                            \
diff --git a/src/base/optional.h b/src/base/optional.h
index 005810a..f2f9233 100644
--- a/src/base/optional.h
+++ b/src/base/optional.h
@@ -14,7 +14,6 @@
 #include "base/logging.h"
 #include "base/template_util.h"
 #include "base/thread_annotations.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
@@ -252,7 +251,7 @@
  protected:
   constexpr OptionalBase() = default;
 #if defined(STARBOARD)
-  CONSTEXPR OptionalBase(const OptionalBase& other) {
+  constexpr OptionalBase(const OptionalBase& other) {
     if (other.storage_.is_populated_)
       storage_.Init(other.storage_.value_);
   }
@@ -626,32 +625,32 @@
     return *this;
   }
 
-  CONSTEXPR const T* operator->() const {
+  constexpr const T* operator->() const {
     DCHECK(storage_.is_populated_);
     return &storage_.value_;
   }
 
-  CONSTEXPR T* operator->() {
+  constexpr T* operator->() {
     DCHECK(storage_.is_populated_);
     return &storage_.value_;
   }
 
-  CONSTEXPR const T& operator*() const & {
+  constexpr const T& operator*() const & {
     DCHECK(storage_.is_populated_);
     return storage_.value_;
   }
 
-  CONSTEXPR T& operator*() & {
+  constexpr T& operator*() & {
     DCHECK(storage_.is_populated_);
     return storage_.value_;
   }
 
-  CONSTEXPR const T&& operator*() const && {
+  constexpr const T&& operator*() const && {
     DCHECK(storage_.is_populated_);
     return std::move(storage_.value_);
   }
 
-  CONSTEXPR T&& operator*() && {
+  constexpr T&& operator*() && {
     DCHECK(storage_.is_populated_);
     return std::move(storage_.value_);
   }
@@ -660,22 +659,22 @@
 
   constexpr bool has_value() const { return storage_.is_populated_; }
 
-  CONSTEXPR T& value() & {
+  constexpr T& value() & {
     CHECK(storage_.is_populated_);
     return storage_.value_;
   }
 
-  CONSTEXPR const T& value() const & {
+  constexpr const T& value() const & {
     CHECK(storage_.is_populated_);
     return storage_.value_;
   }
 
-  CONSTEXPR T&& value() && {
+  constexpr T&& value() && {
     CHECK(storage_.is_populated_);
     return std::move(storage_.value_);
   }
 
-  CONSTEXPR const T&& value() const && {
+  constexpr const T&& value() const && {
     CHECK(storage_.is_populated_);
     return std::move(storage_.value_);
   }
@@ -693,7 +692,7 @@
   }
 
   template <class U>
-  CONSTEXPR T value_or(U&& default_value) && {
+  constexpr T value_or(U&& default_value) && {
     // TODO(mlamouri): add the following assert when possible:
     // static_assert(std::is_move_constructible<T>::value,
     //               "T must be move constructible");
@@ -758,7 +757,7 @@
 // while bool() casting is replaced by has_value() to meet the chromium
 // style guide.
 template <class T, class U>
-CONSTEXPR bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (lhs.has_value() != rhs.has_value())
     return false;
   if (!lhs.has_value())
@@ -767,7 +766,7 @@
 }
 
 template <class T, class U>
-CONSTEXPR bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (lhs.has_value() != rhs.has_value())
     return true;
   if (!lhs.has_value())
@@ -776,7 +775,7 @@
 }
 
 template <class T, class U>
-CONSTEXPR bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (!rhs.has_value())
     return false;
   if (!lhs.has_value())
@@ -785,7 +784,7 @@
 }
 
 template <class T, class U>
-CONSTEXPR bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (!lhs.has_value())
     return true;
   if (!rhs.has_value())
@@ -794,7 +793,7 @@
 }
 
 template <class T, class U>
-CONSTEXPR bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (!lhs.has_value())
     return false;
   if (!rhs.has_value())
@@ -803,7 +802,7 @@
 }
 
 template <class T, class U>
-CONSTEXPR bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
+constexpr bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
   if (!rhs.has_value())
     return true;
   if (!lhs.has_value())
diff --git a/src/base/optional_unittest.cc b/src/base/optional_unittest.cc
index 4e56b96..d504d2b 100644
--- a/src/base/optional_unittest.cc
+++ b/src/base/optional_unittest.cc
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "nb/cpp14oncpp11.h"
 #include "starboard/configuration.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -189,7 +188,7 @@
 
 TEST(OptionalTest, DefaultConstructor) {
   {
-    CONSTEXPR Optional<float> o;
+    constexpr Optional<float> o;
     EXPECT_FALSE(o);
   }
 
@@ -206,7 +205,7 @@
 
 TEST(OptionalTest, CopyConstructor) {
   {
-    CONSTEXPR Optional<float> first(0.1f);
+    constexpr Optional<float> first(0.1f);
 #ifdef STARBOARD
     Optional<float> other(first);
 #else
@@ -248,8 +247,8 @@
 
 TEST(OptionalTest, ValueConstructor) {
   {
-    CONSTEXPR float value = 0.1f;
-    CONSTEXPR Optional<float> o(value);
+    constexpr float value = 0.1f;
+    constexpr Optional<float> o(value);
 
     EXPECT_TRUE(o);
     EXPECT_EQ(value, o.value());
@@ -275,7 +274,7 @@
 
 TEST(OptionalTest, MoveConstructor) {
   {
-    CONSTEXPR Optional<float> first(0.1f);
+    constexpr Optional<float> first(0.1f);
 #ifdef STARBOARD
     Optional<float> second(std::move(first));
 #else
@@ -347,8 +346,8 @@
 
 TEST(OptionalTest, MoveValueConstructor) {
   {
-    CONSTEXPR float value = 0.1f;
-    CONSTEXPR Optional<float> o(std::move(value));
+    constexpr float value = 0.1f;
+    constexpr Optional<float> o(std::move(value));
 
     EXPECT_TRUE(o);
     EXPECT_EQ(0.1f, o.value());
@@ -441,7 +440,7 @@
 
 TEST(OptionalTest, ConstructorForwardArguments) {
   {
-    CONSTEXPR Optional<float> a(base::in_place, 0.1f);
+    constexpr Optional<float> a(base::in_place, 0.1f);
     EXPECT_TRUE(a);
     EXPECT_EQ(0.1f, a.value());
   }
@@ -559,7 +558,7 @@
 }
 
 TEST(OptionalTest, NulloptConstructor) {
-  CONSTEXPR Optional<int> a(base::nullopt);
+  constexpr Optional<int> a(base::nullopt);
   EXPECT_FALSE(a);
 }
 
@@ -1053,15 +1052,15 @@
     EXPECT_EQ(0.0f, a.value_or(0.0f));
   }
 
-  // value_or() can be CONSTEXPR.
+  // value_or() can be constexpr.
   {
-    CONSTEXPR Optional<int> a(in_place, 1);
-    CONSTEXPR int value = a.value_or(10);
+    constexpr Optional<int> a(in_place, 1);
+    constexpr int value = a.value_or(10);
     EXPECT_EQ(1, value);
   }
   {
-    CONSTEXPR Optional<int> a;
-    CONSTEXPR int value = a.value_or(10);
+    constexpr Optional<int> a;
+    constexpr int value = a.value_or(10);
     EXPECT_EQ(10, value);
   }
 
diff --git a/src/base/os_compat_android.cc b/src/base/os_compat_android.cc
index 6c533a5..2a4ecca 100644
--- a/src/base/os_compat_android.cc
+++ b/src/base/os_compat_android.cc
@@ -121,7 +121,7 @@
     return NULL;
   }
 
-  const int path_len = SbStringGetLength(path);
+  const int path_len = strlen(path);
 
   // The last six characters of 'path' must be XXXXXX.
   const base::StringPiece kSuffix("XXXXXX");
diff --git a/src/base/pickle.cc b/src/base/pickle.cc
index 2149e7e..5f01ea8 100644
--- a/src/base/pickle.cc
+++ b/src/base/pickle.cc
@@ -36,7 +36,7 @@
   if (!read_from)
     return false;
   if (sizeof(Type) > sizeof(uint32_t))
-    SbMemoryCopy(result, read_from, sizeof(*result));
+    memcpy(result, read_from, sizeof(*result));
   else
     *result = *reinterpret_cast<const Type*>(read_from);
   return true;
@@ -127,7 +127,7 @@
   const char* read_from = GetReadPointerAndAdvance<float>();
   if (!read_from)
     return false;
-  SbMemoryCopy(result, read_from, sizeof(*result));
+  memcpy(result, read_from, sizeof(*result));
   return true;
 }
 
@@ -139,7 +139,7 @@
   const char* read_from = GetReadPointerAndAdvance<double>();
   if (!read_from)
     return false;
-  SbMemoryCopy(result, read_from, sizeof(*result));
+  memcpy(result, read_from, sizeof(*result));
   return true;
 }
 
@@ -262,7 +262,7 @@
       capacity_after_header_(0),
       write_offset_(other.write_offset_) {
   Resize(other.header_->payload_size);
-  SbMemoryCopy(header_, other.header_,
+  memcpy(header_, other.header_,
                header_size_ + other.header_->payload_size);
 }
 
@@ -285,7 +285,7 @@
     header_size_ = other.header_size_;
   }
   Resize(other.header_->payload_size);
-  SbMemoryCopy(header_, other.header_,
+  memcpy(header_, other.header_,
                other.header_size_ + other.header_->payload_size);
   write_offset_ = other.write_offset_;
   return *this;
@@ -347,7 +347,7 @@
 void* Pickle::ClaimBytes(size_t num_bytes) {
   void* p = ClaimUninitializedBytesInternal(num_bytes);
   CHECK(p);
-  SbMemorySet(p, 0, num_bytes);
+  memset(p, 0, num_bytes);
   return p;
 }
 
@@ -421,7 +421,7 @@
   }
 
   char* write = mutable_payload() + write_offset_;
-  SbMemorySet(write + length, 0,
+  memset(write + length, 0,
               data_len - length);  // Always initialize padding
   header_->payload_size = static_cast<uint32_t>(new_size);
   write_offset_ = new_size;
@@ -433,7 +433,7 @@
       << "oops: pickle is readonly";
   MSAN_CHECK_MEM_IS_INITIALIZED(data, length);
   void* write = ClaimUninitializedBytesInternal(length);
-  SbMemoryCopy(write, data, length);
+  memcpy(write, data, length);
 }
 
 }  // namespace base
diff --git a/src/base/pickle_unittest.cc b/src/base/pickle_unittest.cc
index f5cddbc..7dc9bda 100644
--- a/src/base/pickle_unittest.cc
+++ b/src/base/pickle_unittest.cc
@@ -101,7 +101,7 @@
   int outdatalen;
   EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
   EXPECT_EQ(testdatalen, outdatalen);
-  EXPECT_EQ(SbMemoryCompare(testdata, outdata, outdatalen), 0);
+  EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
 
   // reads past the end should fail
   EXPECT_FALSE(iter.ReadInt(&outint));
@@ -331,7 +331,7 @@
 TEST(PickleTest, FindNextWithIncompleteHeader) {
   size_t header_size = sizeof(Pickle::Header);
   std::unique_ptr<char[]> buffer(new char[header_size - 1]);
-  SbMemorySet(buffer.get(), 0x1, header_size - 1);
+  memset(buffer.get(), 0x1, header_size - 1);
 
   const char* start = buffer.get();
   const char* end = start + header_size - 1;
@@ -506,7 +506,7 @@
   EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data)));
 
   int outdata;
-  SbMemoryCopy(&outdata, outdata_char, sizeof(outdata));
+  memcpy(&outdata, outdata_char, sizeof(outdata));
   EXPECT_EQ(data, outdata);
 }
 
@@ -554,7 +554,7 @@
   pickle.WriteUInt32(data.size());
   void* bytes = pickle.ClaimBytes(data.size());
   pickle.WriteInt(42);
-  SbMemoryCopy(bytes, data.data(), data.size());
+  memcpy(bytes, data.data(), data.size());
 
   PickleIterator iter(pickle);
   uint32_t out_data_length;
diff --git a/src/base/posix/unix_domain_socket.cc b/src/base/posix/unix_domain_socket.cc
index a7226a1..56a5815 100644
--- a/src/base/posix/unix_domain_socket.cc
+++ b/src/base/posix/unix_domain_socket.cc
@@ -92,7 +92,7 @@
     cmsg->cmsg_level = SOL_SOCKET;
     cmsg->cmsg_type = SCM_RIGHTS;
     cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
-    SbMemoryCopy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size());
+    memcpy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size());
     msg.msg_controllen = cmsg->cmsg_len;
   }
 
diff --git a/src/base/posix/unix_domain_socket_unittest.cc b/src/base/posix/unix_domain_socket_unittest.cc
index 25a5907..0466648 100644
--- a/src/base/posix/unix_domain_socket_unittest.cc
+++ b/src/base/posix/unix_domain_socket_unittest.cc
@@ -121,7 +121,7 @@
   const ssize_t nread = UnixDomainSocket::RecvMsgWithPid(
       recv_sock.get(), buf, sizeof(buf), &fd_vec, &sender_pid);
   ASSERT_EQ(sizeof(kHello), static_cast<size_t>(nread));
-  ASSERT_EQ(0, SbMemoryCompare(buf, kHello, sizeof(kHello)));
+  ASSERT_EQ(0, memcmp(buf, kHello, sizeof(kHello)));
   ASSERT_EQ(0U, fd_vec.size());
 
   ASSERT_EQ(getpid(), sender_pid);
@@ -150,7 +150,7 @@
   const ssize_t nread = UnixDomainSocket::RecvMsgWithPid(
       recv_sock.get(), buf, sizeof(buf), &recv_fds, &sender_pid);
   ASSERT_EQ(sizeof(kHello), static_cast<size_t>(nread));
-  ASSERT_EQ(0, SbMemoryCompare(buf, kHello, sizeof(kHello)));
+  ASSERT_EQ(0, memcmp(buf, kHello, sizeof(kHello)));
   ASSERT_EQ(UnixDomainSocket::kMaxFileDescriptors, recv_fds.size());
 
   ASSERT_EQ(getpid(), sender_pid);
diff --git a/src/base/process/launch_posix.cc b/src/base/process/launch_posix.cc
index b4aeebc..e7fe2d6 100644
--- a/src/base/process/launch_posix.cc
+++ b/src/base/process/launch_posix.cc
@@ -443,7 +443,7 @@
     void *malloc_thunk =
         reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
     mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
-    SbMemorySet(reinterpret_cast<void*>(malloc), 0xff, 8);
+    memset(reinterpret_cast<void*>(malloc), 0xff, 8);
 #endif  // 0
 
 #if defined(OS_CHROMEOS)
diff --git a/src/base/process/memory.cc b/src/base/process/memory.cc
index 9e40143..6c7a782 100644
--- a/src/base/process/memory.cc
+++ b/src/base/process/memory.cc
@@ -49,11 +49,7 @@
   if (!UncheckedMalloc(alloc_size, result))
     return false;
 
-#if defined(STARBOARD)
-  SbMemorySet(*result, 0, alloc_size);
-#else
-  SbMemorySet(*result, 0, alloc_size);
-#endif
+  memset(*result, 0, alloc_size);
   return true;
 }
 
diff --git a/src/base/process/process_iterator_win.cc b/src/base/process/process_iterator_win.cc
index 1937c5e..b334218 100644
--- a/src/base/process/process_iterator_win.cc
+++ b/src/base/process/process_iterator_win.cc
@@ -29,7 +29,7 @@
 }
 
 void ProcessIterator::InitProcessEntry(ProcessEntry* entry) {
-  SbMemorySet(entry, 0, sizeof(*entry));
+  memset(entry, 0, sizeof(*entry));
   entry->dwSize = sizeof(*entry);
 }
 
diff --git a/src/base/process/process_metrics_linux.cc b/src/base/process/process_metrics_linux.cc
index 4eceda6..cbb24bb 100644
--- a/src/base/process/process_metrics_linux.cc
+++ b/src/base/process/process_metrics_linux.cc
@@ -713,7 +713,7 @@
     return false;
 
   // mmcblk[0-9]+ case
-  for (size_t i = SbStringGetLength(kMMCName); i < candidate.length(); ++i) {
+  for (size_t i = strlen(kMMCName); i < candidate.length(); ++i) {
     if (!isdigit(candidate[i]))
       return false;
   }
diff --git a/src/base/process/process_metrics_unittest.cc b/src/base/process/process_metrics_unittest.cc
index 3848d2b..1910e02 100644
--- a/src/base/process/process_metrics_unittest.cc
+++ b/src/base/process/process_metrics_unittest.cc
@@ -619,7 +619,7 @@
     const size_t kMappedSize = 4 * (1 << 20);
     SharedMemory memory;
     ASSERT_TRUE(memory.CreateAndMapAnonymous(kMappedSize));
-    SbMemorySet(memory.memory(), 42, kMappedSize);
+    memset(memory.memory(), 42, kMappedSize);
     memory.Unmap();
   }
 
diff --git a/src/base/profiler/native_stack_sampler_mac.cc b/src/base/profiler/native_stack_sampler_mac.cc
index 9d0ecd6..3012ec4 100644
--- a/src/base/profiler/native_stack_sampler_mac.cc
+++ b/src/base/profiler/native_stack_sampler_mac.cc
@@ -479,7 +479,7 @@
   // exactly those registers in exactly the same order, so just bulk copy them
   // over.
   unw_context_t unwind_context;
-  SbMemoryCopy(&unwind_context, &thread_state, sizeof(uintptr_t) * 17);
+  memcpy(&unwind_context, &thread_state, sizeof(uintptr_t) * 17);
   bool result = WalkStackFromContext(&unwind_context, &frame_count, callback,
                                      continue_unwind);
 
diff --git a/src/base/rand_util_unittest.cc b/src/base/rand_util_unittest.cc
index 9906746..4c9e808 100644
--- a/src/base/rand_util_unittest.cc
+++ b/src/base/rand_util_unittest.cc
@@ -43,7 +43,7 @@
 TEST(RandUtilTest, RandBytes) {
   const size_t buffer_size = 50;
   char buffer[buffer_size];
-  SbMemorySet(buffer, 0, buffer_size);
+  memset(buffer, 0, buffer_size);
   base::RandBytes(buffer, buffer_size);
   std::sort(buffer, buffer + buffer_size);
   // Probability of occurrence of less than 25 unique bytes in 50 random bytes
diff --git a/src/base/sha1.cc b/src/base/sha1.cc
index a7d73e7..1594815 100644
--- a/src/base/sha1.cc
+++ b/src/base/sha1.cc
@@ -204,7 +204,7 @@
   sha.Update(data, len);
   sha.Final();
 
-  SbMemoryCopy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
+  memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
 }
 
 }  // namespace base
diff --git a/src/base/stl_util_unittest.cc b/src/base/stl_util_unittest.cc
index 2865b8e..786c44e 100644
--- a/src/base/stl_util_unittest.cc
+++ b/src/base/stl_util_unittest.cc
@@ -24,7 +24,6 @@
 #include "base/containers/queue.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "nb/cpp14oncpp11.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -167,16 +166,10 @@
   }
 
   {
-    CONSTEXPR std::initializer_list<int> il;
-#ifdef STARBOARD
-    // Added extra parentheses as well.
-    STATIC_ASSERT((std::is_same<bool, decltype(base::empty(il))>::value),
-                  "base::empty(il) should be of type bool");
-#else
+    constexpr std::initializer_list<int> il;
     static_assert(std::is_same<bool, decltype(base::empty(il))>::value,
                   "base::empty(il) should be of type bool");
-#endif
-    STATIC_ASSERT(base::empty(il), "base::empty(il) should be true");
+    static_assert(base::empty(il), "base::empty(il) should be true");
   }
 }
 
@@ -236,18 +229,11 @@
   }
 
   {
-    CONSTEXPR std::initializer_list<int> il;
-#ifdef STARBOARD
-    // Added extra parentheses as well.
-    STATIC_ASSERT(
-        (std::is_same<decltype(il.begin()), decltype(base::data(il))>::value),
-        "base::data(il) should have the same type as il.begin()");
-#else
+    constexpr std::initializer_list<int> il;
     static_assert(
         std::is_same<decltype(il.begin()), decltype(base::data(il))>::value,
         "base::data(il) should have the same type as il.begin()");
-#endif
-    STATIC_ASSERT(il.begin() == base::data(il),
+    static_assert(il.begin() == base::data(il),
                   "base::data(il) should be equal to il.begin()");
   }
 }
diff --git a/src/base/strings/char_traits.h b/src/base/strings/char_traits.h
index 5a5d0a4..0a3840c 100644
--- a/src/base/strings/char_traits.h
+++ b/src/base/strings/char_traits.h
@@ -6,7 +6,6 @@
 #define BASE_STRINGS_CHAR_TRAITS_H_
 
 #include "base/compiler_specific.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
@@ -22,14 +21,14 @@
   // Performs a lexographical comparison of the first N characters of |s1| and
   // |s2|. Returns 0 if equal, -1 if |s1| is less than |s2|, and 1 if |s1| is
   // greater than |s2|.
-  static CONSTEXPR int compare(const T* s1, const T* s2, size_t n) noexcept;
+  static constexpr int compare(const T* s1, const T* s2, size_t n) noexcept;
   // Returns the length of |s|, assuming null termination (and not including the
   // terminating null).
-  static CONSTEXPR size_t length(const T* s) noexcept;
+  static constexpr size_t length(const T* s) noexcept;
 };
 
 template <typename T>
-CONSTEXPR int CharTraits<T>::compare(const T* s1,
+constexpr int CharTraits<T>::compare(const T* s1,
                                      const T* s2,
                                      size_t n) noexcept {
   for (; n; --n, ++s1, ++s2) {
@@ -42,7 +41,7 @@
 }
 
 template <typename T>
-CONSTEXPR size_t CharTraits<T>::length(const T* s) noexcept {
+constexpr size_t CharTraits<T>::length(const T* s) noexcept {
   size_t i = 0;
   for (; *s; ++s)
     ++i;
@@ -54,7 +53,7 @@
 #if defined(STARBOARD)
 template <>
 struct CharTraits<char> {
-  CONSTEXPR static int compare(const char* s1,
+  constexpr static int compare(const char* s1,
                                const char* s2,
                                size_t n) noexcept {
     for (; n; --n, ++s1, ++s2) {
@@ -66,7 +65,7 @@
     return 0;
   }
 
-  CONSTEXPR static size_t length(const char* s) noexcept {
+  constexpr static size_t length(const char* s) noexcept {
     size_t i = 0;
     for (; *s; ++s)
       ++i;
diff --git a/src/base/strings/char_traits_unittest.cc b/src/base/strings/char_traits_unittest.cc
index 805044c..9a87b7f 100644
--- a/src/base/strings/char_traits_unittest.cc
+++ b/src/base/strings/char_traits_unittest.cc
@@ -6,29 +6,28 @@
 #include "base/strings/string16.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
 TEST(CharTraitsTest, CharCompare) {
-  STATIC_ASSERT(CharTraits<char>::compare("abc", "def", 3) == -1, "");
-  STATIC_ASSERT(CharTraits<char>::compare("def", "def", 3) == 0, "");
-  STATIC_ASSERT(CharTraits<char>::compare("ghi", "def", 3) == 1, "");
+  static_assert(CharTraits<char>::compare("abc", "def", 3) == -1, "");
+  static_assert(CharTraits<char>::compare("def", "def", 3) == 0, "");
+  static_assert(CharTraits<char>::compare("ghi", "def", 3) == 1, "");
 }
 
 TEST(CharTraitsTest, CharLength) {
-  STATIC_ASSERT(CharTraits<char>::length("") == 0, "");
-  STATIC_ASSERT(CharTraits<char>::length("abc") == 3, "");
+  static_assert(CharTraits<char>::length("") == 0, "");
+  static_assert(CharTraits<char>::length("abc") == 3, "");
 }
 
 TEST(CharTraitsTest, Char16TCompare) {
-  STATIC_ASSERT(CharTraits<char16_t>::compare(u"abc", u"def", 3) == -1, "");
-  STATIC_ASSERT(CharTraits<char16_t>::compare(u"def", u"def", 3) == 0, "");
-  STATIC_ASSERT(CharTraits<char16_t>::compare(u"ghi", u"def", 3) == 1, "");
+  static_assert(CharTraits<char16_t>::compare(u"abc", u"def", 3) == -1, "");
+  static_assert(CharTraits<char16_t>::compare(u"def", u"def", 3) == 0, "");
+  static_assert(CharTraits<char16_t>::compare(u"ghi", u"def", 3) == 1, "");
 }
 
 TEST(CharTraitsTest, Char16TLength) {
-  STATIC_ASSERT(CharTraits<char16_t>::length(u"abc") == 3, "");
+  static_assert(CharTraits<char16_t>::length(u"abc") == 3, "");
 }
 
 }  // namespace base
diff --git a/src/base/strings/pattern.cc b/src/base/strings/pattern.cc
index d71f7dc..f3de0af 100644
--- a/src/base/strings/pattern.cc
+++ b/src/base/strings/pattern.cc
@@ -5,7 +5,6 @@
 #include "base/strings/pattern.h"
 
 #include "base/third_party/icu/icu_utf.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
@@ -20,7 +19,7 @@
 // the first wildcard character (or the end of the string). If the value of
 // |maximum_distance| is negative, the maximum distance is considered infinite.
 template <typename CHAR, typename NEXT>
-CONSTEXPR bool SearchForChars(const CHAR** pattern,
+constexpr bool SearchForChars(const CHAR** pattern,
                               const CHAR* pattern_end,
                               const CHAR** string,
                               const CHAR* string_end,
@@ -88,7 +87,7 @@
 // match an arbitrary number of characters (which is the case if it contains at
 // least one *).
 template <typename CHAR, typename NEXT>
-CONSTEXPR int EatWildcards(const CHAR** pattern, const CHAR* end, NEXT next) {
+constexpr int EatWildcards(const CHAR** pattern, const CHAR* end, NEXT next) {
   int num_question_marks = 0;
   bool has_asterisk = false;
   while (*pattern != end) {
@@ -106,7 +105,7 @@
 }
 
 template <typename CHAR, typename NEXT>
-CONSTEXPR bool MatchPatternT(const CHAR* eval,
+constexpr bool MatchPatternT(const CHAR* eval,
                              const CHAR* eval_end,
                              const CHAR* pattern,
                              const CHAR* pattern_end,
diff --git a/src/base/strings/safe_sprintf_unittest.cc b/src/base/strings/safe_sprintf_unittest.cc
index 29de95a..912db4c 100644
--- a/src/base/strings/safe_sprintf_unittest.cc
+++ b/src/base/strings/safe_sprintf_unittest.cc
@@ -70,46 +70,46 @@
   // always add a trailing NUL; it always deduplicates '%' characters).
   static const char text[] = "hello world";
   char ref[20], buf[20];
-  SbMemorySet(ref, 'X', sizeof(ref));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memset(ref, 'X', sizeof(ref));
+  memcpy(buf, ref, sizeof(buf));
 
   // A negative buffer size should always result in an error.
   EXPECT_EQ(-1, SafeSNPrintf(buf, static_cast<size_t>(-1), text));
-  EXPECT_TRUE(!SbMemoryCompare(buf, ref, sizeof(buf)));
+  EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
 
   // Zero buffer size should always result in an error.
   EXPECT_EQ(-1, SafeSNPrintf(buf, 0, text));
-  EXPECT_TRUE(!SbMemoryCompare(buf, ref, sizeof(buf)));
+  EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
 
   // A one-byte buffer should always print a single NUL byte.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 1, text));
   EXPECT_EQ(0, buf[0]);
-  EXPECT_TRUE(!SbMemoryCompare(buf + 1, ref + 1, sizeof(buf) - 1));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  EXPECT_TRUE(!memcmp(buf + 1, ref + 1, sizeof(buf) - 1));
+  memcpy(buf, ref, sizeof(buf));
 
   // A larger (but limited) buffer should always leave the trailing bytes
   // unchanged.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 2, text));
   EXPECT_EQ(text[0], buf[0]);
   EXPECT_EQ(0, buf[1]);
-  EXPECT_TRUE(!SbMemoryCompare(buf + 2, ref + 2, sizeof(buf) - 2));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  EXPECT_TRUE(!memcmp(buf + 2, ref + 2, sizeof(buf) - 2));
+  memcpy(buf, ref, sizeof(buf));
 
   // A unrestricted buffer length should always leave the trailing bytes
   // unchanged.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
             SafeSNPrintf(buf, sizeof(buf), text));
   EXPECT_EQ(std::string(text), std::string(buf));
-  EXPECT_TRUE(!SbMemoryCompare(buf + sizeof(text), ref + sizeof(text),
+  EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
                                sizeof(buf) - sizeof(text)));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memcpy(buf, ref, sizeof(buf));
 
   // The same test using SafeSPrintf() instead of SafeSNPrintf().
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, text));
   EXPECT_EQ(std::string(text), std::string(buf));
-  EXPECT_TRUE(!SbMemoryCompare(buf + sizeof(text), ref + sizeof(text),
+  EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
                                sizeof(buf) - sizeof(text)));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memcpy(buf, ref, sizeof(buf));
 
   // Check for deduplication of '%' percent characters.
   EXPECT_EQ(1, SafeSPrintf(buf, "%%"));
@@ -134,23 +134,23 @@
   const char text[] = "hello world";
   const char fmt[]  = "hello%cworld";
   char ref[20], buf[20];
-  SbMemorySet(ref, 'X', sizeof(buf));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memset(ref, 'X', sizeof(buf));
+  memcpy(buf, ref, sizeof(buf));
 
   // A negative buffer size should always result in an error.
   EXPECT_EQ(-1, SafeSNPrintf(buf, static_cast<size_t>(-1), fmt, ' '));
-  EXPECT_TRUE(!SbMemoryCompare(buf, ref, sizeof(buf)));
+  EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
 
   // Zero buffer size should always result in an error.
   EXPECT_EQ(-1, SafeSNPrintf(buf, 0, fmt, ' '));
-  EXPECT_TRUE(!SbMemoryCompare(buf, ref, sizeof(buf)));
+  EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
 
   // A one-byte buffer should always print a single NUL byte.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
             SafeSNPrintf(buf, 1, fmt, ' '));
   EXPECT_EQ(0, buf[0]);
-  EXPECT_TRUE(!SbMemoryCompare(buf + 1, ref + 1, sizeof(buf) - 1));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  EXPECT_TRUE(!memcmp(buf + 1, ref + 1, sizeof(buf) - 1));
+  memcpy(buf, ref, sizeof(buf));
 
   // A larger (but limited) buffer should always leave the trailing bytes
   // unchanged.
@@ -158,24 +158,24 @@
             SafeSNPrintf(buf, 2, fmt, ' '));
   EXPECT_EQ(text[0], buf[0]);
   EXPECT_EQ(0, buf[1]);
-  EXPECT_TRUE(!SbMemoryCompare(buf + 2, ref + 2, sizeof(buf) - 2));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  EXPECT_TRUE(!memcmp(buf + 2, ref + 2, sizeof(buf) - 2));
+  memcpy(buf, ref, sizeof(buf));
 
   // A unrestricted buffer length should always leave the trailing bytes
   // unchanged.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
             SafeSNPrintf(buf, sizeof(buf), fmt, ' '));
   EXPECT_EQ(std::string(text), std::string(buf));
-  EXPECT_TRUE(!SbMemoryCompare(buf + sizeof(text), ref + sizeof(text),
+  EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
                                sizeof(buf) - sizeof(text)));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memcpy(buf, ref, sizeof(buf));
 
   // The same test using SafeSPrintf() instead of SafeSNPrintf().
   EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, fmt, ' '));
   EXPECT_EQ(std::string(text), std::string(buf));
-  EXPECT_TRUE(!SbMemoryCompare(buf + sizeof(text), ref + sizeof(text),
+  EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
                                sizeof(buf) - sizeof(text)));
-  SbMemoryCopy(buf, ref, sizeof(buf));
+  memcpy(buf, ref, sizeof(buf));
 
   // Check for deduplication of '%' percent characters.
   EXPECT_EQ(1, SafeSPrintf(buf, "%%", 0));
@@ -359,10 +359,10 @@
   SafeSPrintf(buf, "%019p", buf);
   EXPECT_EQ(std::string(addr), std::string(buf));
   sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf);
-  SbMemorySet(
+  memset(
       addr, ' ',
-      (char*)SbMemoryMove(addr + sizeof(addr) - SbStringGetLength(addr) - 1,
-                          addr, SbStringGetLength(addr) + 1) -
+      (char*)memmove(addr + sizeof(addr) - strlen(addr) - 1,
+                          addr, strlen(addr) + 1) -
           addr);
   SafeSPrintf(buf, "%19p", buf);
   EXPECT_EQ(std::string(addr), std::string(buf));
@@ -377,7 +377,7 @@
   // Allocate slightly more space, so that we can verify that SafeSPrintf()
   // never writes past the end of the buffer.
   std::unique_ptr<char[]> tmp(new char[sz + 2]);
-  SbMemorySet(tmp.get(), 'X', sz + 2);
+  memset(tmp.get(), 'X', sz + 2);
 
   // Use SafeSPrintf() to output a complex list of arguments:
   // - test padding and truncating %c single characters.
@@ -405,7 +405,7 @@
     // Various sanity checks:
     // The numbered of characters needed to print the full string should always
     // be bigger or equal to the bytes that have actually been output.
-    len = SbStringGetLength(tmp.get());
+    len = strlen(tmp.get());
     CHECK_GE(needed, len+1);
 
     // The number of characters output should always fit into the buffer that
@@ -462,7 +462,7 @@
   // We allocated a slightly larger buffer, so that we could perform some
   // extra sanity checks. Now that the tests have all passed, we copy the
   // data to the output buffer that the caller provided.
-  SbMemoryCopy(buf, tmp.get(), len + 1);
+  memcpy(buf, tmp.get(), len + 1);
 }
 
 #if !defined(NDEBUG)
@@ -493,7 +493,7 @@
   // happen in a lot of different states.
   char ref[256];
   PrintLongString(ref, sizeof(ref));
-  for (size_t i = SbStringGetLength(ref) + 1; i; --i) {
+  for (size_t i = strlen(ref) + 1; i; --i) {
     char buf[sizeof(ref)];
     PrintLongString(buf, i);
     EXPECT_EQ(std::string(ref, i - 1), std::string(buf));
@@ -506,7 +506,7 @@
   // Repeat the truncation test and verify that this other code path in
   // SafeSPrintf() works correctly, too.
 #if !defined(NDEBUG)
-  for (size_t i = SbStringGetLength(ref) + 1; i > 1; --i) {
+  for (size_t i = strlen(ref) + 1; i > 1; --i) {
     ScopedSafeSPrintfSSizeMaxSetter ssize_max_setter(i);
     char buf[sizeof(ref)];
     PrintLongString(buf, sizeof(buf));
diff --git a/src/base/strings/string16.cc b/src/base/strings/string16.cc
index af5e014..091d8ee 100644
--- a/src/base/strings/string16.cc
+++ b/src/base/strings/string16.cc
@@ -58,11 +58,11 @@
 }
 
 char16* c16SbMemoryMove(char16* s1, const char16* s2, size_t n) {
-  return static_cast<char16*>(SbMemoryMove(s1, s2, n * sizeof(char16)));
+  return static_cast<char16*>(memmove(s1, s2, n * sizeof(char16)));
 }
 
 char16* c16SbMemoryCopy(char16* s1, const char16* s2, size_t n) {
-  return static_cast<char16*>(SbMemoryCopy(s1, s2, n * sizeof(char16)));
+  return static_cast<char16*>(memcpy(s1, s2, n * sizeof(char16)));
 }
 
 char16* c16SbMemorySet(char16* s, char16 c, size_t n) {
diff --git a/src/base/strings/string_number_conversions.cc b/src/base/strings/string_number_conversions.cc
index 8a57e5e..9995ac8 100644
--- a/src/base/strings/string_number_conversions.cc
+++ b/src/base/strings/string_number_conversions.cc
@@ -377,7 +377,7 @@
 
   // The number will be ASCII. This creates the string using the "input
   // iterator" variant which promotes from 8-bit to 16-bit via "=".
-  return base::string16(&buffer[0], &buffer[SbStringGetLength(buffer)]);
+  return base::string16(&buffer[0], &buffer[strlen(buffer)]);
 }
 
 bool StringToInt(StringPiece input, int* output) {
diff --git a/src/base/strings/string_number_conversions_unittest.cc b/src/base/strings/string_number_conversions_unittest.cc
index 4cd2d3a..c2c4804 100644
--- a/src/base/strings/string_number_conversions_unittest.cc
+++ b/src/base/strings/string_number_conversions_unittest.cc
@@ -863,12 +863,12 @@
   // The following two values were seen in crashes in the wild.
   const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
   double input = 0;
-  SbMemoryCopy(&input, input_bytes, arraysize(input_bytes));
+  memcpy(&input, input_bytes, arraysize(input_bytes));
   EXPECT_EQ("1335179083776", NumberToString(input));
   const char input_bytes2[8] =
       {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'};
   input = 0;
-  SbMemoryCopy(&input, input_bytes2, arraysize(input_bytes2));
+  memcpy(&input, input_bytes2, arraysize(input_bytes2));
   EXPECT_EQ("1334890332160", NumberToString(input));
 }
 
diff --git a/src/base/strings/string_piece.cc b/src/base/strings/string_piece.cc
index 50e48a0..70e6a29 100644
--- a/src/base/strings/string_piece.cc
+++ b/src/base/strings/string_piece.cc
@@ -93,7 +93,7 @@
              size_t n,
              size_t pos) {
   size_t ret = std::min(self.size() - pos, n);
-  SbMemoryCopy(buf, self.data() + pos, ret * sizeof(typename STR::value_type));
+  memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type));
   return ret;
 }
 
diff --git a/src/base/strings/string_piece.h b/src/base/strings/string_piece.h
index 5c151ce..4062bc9 100644
--- a/src/base/strings/string_piece.h
+++ b/src/base/strings/string_piece.h
@@ -30,7 +30,6 @@
 #include "base/strings/char_traits.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_piece_forward.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
@@ -205,9 +204,9 @@
   // returned buffer may or may not be null terminated.  Therefore it is
   // typically a mistake to pass data() to a routine that expects a NUL
   // terminated string.
-  CONSTEXPR const value_type* data() const { return ptr_; }
-  CONSTEXPR size_type size() const { return length_; }
-  CONSTEXPR size_type length() const { return length_; }
+  constexpr const value_type* data() const { return ptr_; }
+  constexpr size_type size() const { return length_; }
+  constexpr size_type length() const { return length_; }
   bool empty() const { return length_ == 0; }
 
   void clear() {
@@ -223,7 +222,7 @@
     length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
   }
 
-  CONSTEXPR value_type operator[](size_type i) const {
+  constexpr value_type operator[](size_type i) const {
     CHECK(i < length_);
     return ptr_[i];
   }
@@ -238,18 +237,18 @@
     return ptr_[length_ - 1];
   }
 
-  CONSTEXPR void remove_prefix(size_type n) {
+  constexpr void remove_prefix(size_type n) {
     CHECK(n <= length_);
     ptr_ += n;
     length_ -= n;
   }
 
-  CONSTEXPR void remove_suffix(size_type n) {
+  constexpr void remove_suffix(size_type n) {
     CHECK(n <= length_);
     length_ -= n;
   }
 
-  CONSTEXPR int compare(BasicStringPiece x) const noexcept {
+  constexpr int compare(BasicStringPiece x) const noexcept {
     int r = CharTraits<value_type>::compare(
         ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
     if (r == 0) {
diff --git a/src/base/strings/string_piece_unittest.cc b/src/base/strings/string_piece_unittest.cc
index 498cbd9..a65ecb7 100644
--- a/src/base/strings/string_piece_unittest.cc
+++ b/src/base/strings/string_piece_unittest.cc
@@ -7,7 +7,6 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -708,98 +707,98 @@
 
 TEST(StringPieceTest, CONSTEXPRCtor) {
   {
-    CONSTEXPR StringPiece piece;
+    constexpr StringPiece piece;
     std::ignore = piece;
   }
 
   {
-    CONSTEXPR StringPiece piece("abc");
+    constexpr StringPiece piece("abc");
     std::ignore = piece;
   }
 
   {
-    CONSTEXPR StringPiece piece("abc", 2);
+    constexpr StringPiece piece("abc", 2);
     std::ignore = piece;
   }
 }
 
 TEST(StringPieceTest, CONSTEXPRData) {
   {
-    CONSTEXPR StringPiece piece;
-    STATIC_ASSERT(piece.data() == nullptr, "");
+    constexpr StringPiece piece;
+    static_assert(piece.data() == nullptr, "");
   }
 
   {
-    CONSTEXPR StringPiece piece("abc");
-    STATIC_ASSERT(piece.data()[0] == 'a', "");
-    STATIC_ASSERT(piece.data()[1] == 'b', "");
-    STATIC_ASSERT(piece.data()[2] == 'c', "");
+    constexpr StringPiece piece("abc");
+    static_assert(piece.data()[0] == 'a', "");
+    static_assert(piece.data()[1] == 'b', "");
+    static_assert(piece.data()[2] == 'c', "");
   }
 
   {
-    CONSTEXPR StringPiece piece("def", 2);
-    STATIC_ASSERT(piece.data()[0] == 'd', "");
-    STATIC_ASSERT(piece.data()[1] == 'e', "");
+    constexpr StringPiece piece("def", 2);
+    static_assert(piece.data()[0] == 'd', "");
+    static_assert(piece.data()[1] == 'e', "");
   }
 }
 
 TEST(StringPieceTest, CONSTEXPRSize) {
   {
-    CONSTEXPR StringPiece piece;
-    STATIC_ASSERT(piece.size() == 0, "");
+    constexpr StringPiece piece;
+    static_assert(piece.size() == 0, "");
   }
 
   {
-    CONSTEXPR StringPiece piece("abc");
-    STATIC_ASSERT(piece.size() == 3, "");
+    constexpr StringPiece piece("abc");
+    static_assert(piece.size() == 3, "");
   }
 
   {
-    CONSTEXPR StringPiece piece("def", 2);
-    STATIC_ASSERT(piece.size() == 2, "");
+    constexpr StringPiece piece("def", 2);
+    static_assert(piece.size() == 2, "");
   }
 }
 
 TEST(StringPieceTest, Compare) {
-  CONSTEXPR StringPiece piece = "def";
+  constexpr StringPiece piece = "def";
 
-  STATIC_ASSERT(piece.compare("ab") == 1, "");
-  STATIC_ASSERT(piece.compare("abc") == 1, "");
-  STATIC_ASSERT(piece.compare("abcd") == 1, "");
-  STATIC_ASSERT(piece.compare("de") == 1, "");
-  STATIC_ASSERT(piece.compare("def") == 0, "");
-  STATIC_ASSERT(piece.compare("defg") == -1, "");
-  STATIC_ASSERT(piece.compare("gh") == -1, "");
-  STATIC_ASSERT(piece.compare("ghi") == -1, "");
-  STATIC_ASSERT(piece.compare("ghij") == -1, "");
+  static_assert(piece.compare("ab") == 1, "");
+  static_assert(piece.compare("abc") == 1, "");
+  static_assert(piece.compare("abcd") == 1, "");
+  static_assert(piece.compare("de") == 1, "");
+  static_assert(piece.compare("def") == 0, "");
+  static_assert(piece.compare("defg") == -1, "");
+  static_assert(piece.compare("gh") == -1, "");
+  static_assert(piece.compare("ghi") == -1, "");
+  static_assert(piece.compare("ghij") == -1, "");
 }
 
 TEST(StringPieceTest, StartsWith) {
-  CONSTEXPR StringPiece piece("abc");
+  constexpr StringPiece piece("abc");
 
-  STATIC_ASSERT(piece.starts_with(""), "");
-  STATIC_ASSERT(piece.starts_with("a"), "");
-  STATIC_ASSERT(piece.starts_with("ab"), "");
-  STATIC_ASSERT(piece.starts_with("abc"), "");
+  static_assert(piece.starts_with(""), "");
+  static_assert(piece.starts_with("a"), "");
+  static_assert(piece.starts_with("ab"), "");
+  static_assert(piece.starts_with("abc"), "");
 
-  STATIC_ASSERT(!piece.starts_with("b"), "");
-  STATIC_ASSERT(!piece.starts_with("bc"), "");
+  static_assert(!piece.starts_with("b"), "");
+  static_assert(!piece.starts_with("bc"), "");
 
-  STATIC_ASSERT(!piece.starts_with("abcd"), "");
+  static_assert(!piece.starts_with("abcd"), "");
 }
 
 TEST(StringPieceTest, EndsWith) {
-  CONSTEXPR StringPiece piece("abc");
+  constexpr StringPiece piece("abc");
 
-  STATIC_ASSERT(piece.ends_with(""), "");
-  STATIC_ASSERT(piece.ends_with("c"), "");
-  STATIC_ASSERT(piece.ends_with("bc"), "");
-  STATIC_ASSERT(piece.ends_with("abc"), "");
+  static_assert(piece.ends_with(""), "");
+  static_assert(piece.ends_with("c"), "");
+  static_assert(piece.ends_with("bc"), "");
+  static_assert(piece.ends_with("abc"), "");
 
-  STATIC_ASSERT(!piece.ends_with("a"), "");
-  STATIC_ASSERT(!piece.ends_with("ab"), "");
+  static_assert(!piece.ends_with("a"), "");
+  static_assert(!piece.ends_with("ab"), "");
 
-  STATIC_ASSERT(!piece.ends_with("abcd"), "");
+  static_assert(!piece.ends_with("abcd"), "");
 }
 
 }  // namespace base
diff --git a/src/base/strings/string_util_starboard.h b/src/base/strings/string_util_starboard.h
index 65cbc77..9de5572 100644
--- a/src/base/strings/string_util_starboard.h
+++ b/src/base/strings/string_util_starboard.h
@@ -48,7 +48,7 @@
 
 inline int strncmp16(const char16* s1, const char16* s2, size_t count) {
 #if defined(WCHAR_T_IS_UTF16)
-  return SbStringCompareWide(s1, s2, count);
+  return wcsncmp(s1, s2, count);
 #elif defined(WCHAR_T_IS_UTF32)
   return c16SbMemoryCompare(s1, s2, count);
 #endif
diff --git a/src/base/strings/string_util_unittest.cc b/src/base/strings/string_util_unittest.cc
index e9105ea..474358a 100644
--- a/src/base/strings/string_util_unittest.cc
+++ b/src/base/strings/string_util_unittest.cc
@@ -1108,9 +1108,9 @@
     char dst[10];
     wchar_t wdst[10];
     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", arraysize(dst)));
-    EXPECT_EQ(0, SbMemoryCompare(dst, "abcdefg", 8));
+    EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
-    EXPECT_EQ(0, SbMemoryCompare(wdst, L"abcdefg", sizeof(wchar_t) * 8));
+    EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
   }
 
   // Test dst_size == 0, nothing should be written to |dst| and we should
@@ -1131,9 +1131,9 @@
     char dst[8];
     wchar_t wdst[8];
     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", arraysize(dst)));
-    EXPECT_EQ(0, SbMemoryCompare(dst, "abcdefg", 8));
+    EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
-    EXPECT_EQ(0, SbMemoryCompare(wdst, L"abcdefg", sizeof(wchar_t) * 8));
+    EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
   }
 
   // Test the case were we we are one smaller, so we can't fit the null.
@@ -1141,9 +1141,9 @@
     char dst[7];
     wchar_t wdst[7];
     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", arraysize(dst)));
-    EXPECT_EQ(0, SbMemoryCompare(dst, "abcdef", 7));
+    EXPECT_EQ(0, memcmp(dst, "abcdef", 7));
     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
-    EXPECT_EQ(0, SbMemoryCompare(wdst, L"abcdef", sizeof(wchar_t) * 7));
+    EXPECT_EQ(0, memcmp(wdst, L"abcdef", sizeof(wchar_t) * 7));
   }
 
   // Test the case were we are just too small.
@@ -1151,9 +1151,9 @@
     char dst[3];
     wchar_t wdst[3];
     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", arraysize(dst)));
-    EXPECT_EQ(0, SbMemoryCompare(dst, "ab", 3));
+    EXPECT_EQ(0, memcmp(dst, "ab", 3));
     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
-    EXPECT_EQ(0, SbMemoryCompare(wdst, L"ab", sizeof(wchar_t) * 3));
+    EXPECT_EQ(0, memcmp(wdst, L"ab", sizeof(wchar_t) * 3));
   }
 }
 
@@ -1265,7 +1265,7 @@
     // Test with an input/output var of ample capacity; should
     // not realloc.
     std::string input_output = scenario.input;
-    input_output.reserve(SbStringGetLength(scenario.output) * 2);
+    input_output.reserve(strlen(scenario.output) * 2);
     const void* original_buffer = input_output.data();
     bool result = ReplaceChars(input_output, scenario.replace_chars,
                                scenario.replace_with, &input_output);
@@ -1348,7 +1348,7 @@
   static void WritesCorrectly(size_t num_chars) {
     std::string buffer;
     char kOriginal[] = "supercali";
-    PoemStringCopyN(WriteInto(&buffer, num_chars + 1), kOriginal, num_chars);
+    starboard::strlcpy(WriteInto(&buffer, num_chars + 1), kOriginal, num_chars + 1);
     // Using std::string(buffer.c_str()) instead of |buffer| truncates the
     // string at the first \0.
     EXPECT_EQ(std::string(kOriginal,
@@ -1371,7 +1371,7 @@
   const char kDead[] = "dead";
   const std::string live = kLive;
   std::string dead = live;
-  PoemStringCopyN(WriteInto(&dead, 5), kDead, 4);
+  starboard::strlcpy(WriteInto(&dead, 5), kDead, 5);
   EXPECT_EQ(kDead, dead);
   EXPECT_EQ(4u, dead.size());
   EXPECT_EQ(kLive, live);
diff --git a/src/base/strings/sys_string_conversions_posix.cc b/src/base/strings/sys_string_conversions_posix.cc
index e5fb69f..b9ff1dc 100644
--- a/src/base/strings/sys_string_conversions_posix.cc
+++ b/src/base/strings/sys_string_conversions_posix.cc
@@ -47,7 +47,7 @@
   // Calculate the number of multi-byte characters.  We walk through the string
   // without writing the output, counting the number of multi-byte characters.
   size_t num_out_chars = 0;
-  SbMemorySet(&ps, 0, sizeof(ps));
+  memset(&ps, 0, sizeof(ps));
   for (size_t i = 0; i < wide.size(); ++i) {
     const wchar_t src = wide[i];
     // Use a temp buffer since calling wcrtomb with an output of NULL does not
@@ -78,7 +78,7 @@
 
   // We walk the input string again, with |i| tracking the index of the
   // wide input, and |j| tracking the multi-byte output.
-  SbMemorySet(&ps, 0, sizeof(ps));
+  memset(&ps, 0, sizeof(ps));
   for (size_t i = 0, j = 0; i < wide.size(); ++i) {
     const wchar_t src = wide[i];
     // We don't want wcrtomb to do its funkiness for embedded NULLs.
@@ -107,7 +107,7 @@
   // Calculate the number of wide characters.  We walk through the string
   // without writing the output, counting the number of wide characters.
   size_t num_out_chars = 0;
-  SbMemorySet(&ps, 0, sizeof(ps));
+  memset(&ps, 0, sizeof(ps));
   for (size_t i = 0; i < native_mb.size(); ) {
     const char* src = native_mb.data() + i;
     size_t res = mbrtowc(nullptr, src, native_mb.size() - i, &ps);
@@ -134,7 +134,7 @@
   std::wstring out;
   out.resize(num_out_chars);
 
-  SbMemorySet(&ps, 0, sizeof(ps));  // Clear the shift state.
+  memset(&ps, 0, sizeof(ps));  // Clear the shift state.
   // We walk the input string again, with |i| tracking the index of the
   // multi-byte input, and |j| tracking the wide output.
   for (size_t i = 0, j = 0; i < native_mb.size(); ++j) {
diff --git a/src/base/strings/utf_string_conversions.cc b/src/base/strings/utf_string_conversions.cc
index 1f77ffb..a83d106 100644
--- a/src/base/strings/utf_string_conversions.cc
+++ b/src/base/strings/utf_string_conversions.cc
@@ -9,7 +9,6 @@
 #include "base/strings/utf_string_conversion_utils.h"
 #include "base/third_party/icu/icu_utf.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
diff --git a/src/base/strings/utf_string_conversions_unittest.cc b/src/base/strings/utf_string_conversions_unittest.cc
index 0dfd72f..941e489 100644
--- a/src/base/strings/utf_string_conversions_unittest.cc
+++ b/src/base/strings/utf_string_conversions_unittest.cc
@@ -102,7 +102,7 @@
     std::wstring converted;
     EXPECT_EQ(convert_cases[i].success,
               UTF8ToWide(convert_cases[i].utf8,
-                         SbStringGetLength(convert_cases[i].utf8), &converted));
+                         strlen(convert_cases[i].utf8), &converted));
     std::wstring expected(convert_cases[i].wide);
     EXPECT_EQ(expected, converted);
   }
@@ -197,11 +197,11 @@
     '\0'
   };
   string16 multistring16;
-  SbMemoryCopy(WriteInto(&multistring16, arraysize(multi16)), multi16,
+  memcpy(WriteInto(&multistring16, arraysize(multi16)), multi16,
                sizeof(multi16));
   EXPECT_EQ(arraysize(multi16) - 1, multistring16.length());
   std::string expected;
-  SbMemoryCopy(WriteInto(&expected, arraysize(multi)), multi, sizeof(multi));
+  memcpy(WriteInto(&expected, arraysize(multi)), multi, sizeof(multi));
   EXPECT_EQ(arraysize(multi) - 1, expected.length());
   const std::string& converted = UTF16ToUTF8(multistring16);
   EXPECT_EQ(arraysize(multi) - 1, converted.length());
diff --git a/src/base/sys_info_linux.cc b/src/base/sys_info_linux.cc
index 55cffc3..09a8d5a 100644
--- a/src/base/sys_info_linux.cc
+++ b/src/base/sys_info_linux.cc
@@ -82,7 +82,7 @@
     std::istringstream iss(contents);
     std::string line;
     while (std::getline(iss, line)) {
-      if (line.compare(0, SbStringGetLength(kCpuModelPrefix),
+      if (line.compare(0, strlen(kCpuModelPrefix),
                        kCpuModelPrefix) == 0) {
         size_t pos = line.find(": ");
         return line.substr(pos + 2);
diff --git a/src/base/task/lazy_task_runner.h b/src/base/task/lazy_task_runner.h
index 237c0d1..03bdf6a 100644
--- a/src/base/task/lazy_task_runner.h
+++ b/src/base/task/lazy_task_runner.h
@@ -17,7 +17,6 @@
 #include "base/task/task_scheduler/scheduler_lock.h"
 #include "base/task/task_traits.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 
 // Lazy(Sequenced|SingleThread|COMSTA)TaskRunner lazily creates a TaskRunner.
 //
@@ -96,7 +95,7 @@
 // |traits| are TaskTraits used when creating the SequencedTaskRunner.
 #define LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER(traits)        \
   base::LazySequencedTaskRunner::CreateInternal(traits);      \
-  ALLOW_UNUSED_TYPE CONSTEXPR                                 \
+  ALLOW_UNUSED_TYPE constexpr                                 \
       base::TaskTraits LAZY_TASK_RUNNER_CONCATENATE_INTERNAL( \
           kVerifyTraitsAreConstexpr, __LINE__) = traits
 
@@ -105,10 +104,10 @@
 // thread with other SingleThreadTaskRunners.
 #define LAZY_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(traits, thread_mode)   \
   base::LazySingleThreadTaskRunner::CreateInternal(traits, thread_mode);  \
-  ALLOW_UNUSED_TYPE CONSTEXPR                                             \
+  ALLOW_UNUSED_TYPE constexpr                                             \
       base::TaskTraits LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(             \
           kVerifyTraitsAreConstexpr, __LINE__) = traits;                  \
-  ALLOW_UNUSED_TYPE CONSTEXPR base::SingleThreadTaskRunnerThreadMode      \
+  ALLOW_UNUSED_TYPE constexpr base::SingleThreadTaskRunnerThreadMode      \
       LAZY_TASK_RUNNER_CONCATENATE_INTERNAL(kVerifyThreadModeIsConstexpr, \
                                             __LINE__) = thread_mode
 
diff --git a/src/base/task/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc b/src/base/task/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
index 8d4e0b0..0f412fb 100644
--- a/src/base/task/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
+++ b/src/base/task/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
@@ -24,7 +24,6 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_WIN)
@@ -303,7 +302,7 @@
 }
 
 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, ThreadNamesSet) {
-  CONSTEXPR TaskTraits foo_traits = {TaskPriority::BEST_EFFORT,
+  constexpr TaskTraits foo_traits = {TaskPriority::BEST_EFFORT,
                                      TaskShutdownBehavior::BLOCK_SHUTDOWN};
   scoped_refptr<SingleThreadTaskRunner> foo_task_runner =
       single_thread_task_runner_manager_
@@ -312,7 +311,7 @@
   foo_task_runner->PostTask(FROM_HERE,
                             BindOnce(&CaptureThreadName, &foo_captured_name));
 
-  CONSTEXPR TaskTraits user_blocking_traits = {
+  constexpr TaskTraits user_blocking_traits = {
       TaskPriority::USER_BLOCKING, MayBlock(),
       TaskShutdownBehavior::BLOCK_SHUTDOWN};
   scoped_refptr<SingleThreadTaskRunner> user_blocking_task_runner =
diff --git a/src/base/task/task_scheduler/service_thread.cc b/src/base/task/task_scheduler/service_thread.cc
index c2bea34..be315c1 100644
--- a/src/base/task/task_scheduler/service_thread.cc
+++ b/src/base/task/task_scheduler/service_thread.cc
@@ -71,7 +71,7 @@
   if (!task_tracker_)
     return;
 
-  static CONSTEXPR TaskTraits kReportedTraits[] = {
+  static constexpr TaskTraits kReportedTraits[] = {
       {TaskPriority::BEST_EFFORT},   {TaskPriority::BEST_EFFORT, MayBlock()},
       {TaskPriority::USER_VISIBLE},  {TaskPriority::USER_VISIBLE, MayBlock()},
       {TaskPriority::USER_BLOCKING}, {TaskPriority::USER_BLOCKING, MayBlock()}};
diff --git a/src/base/task/task_scheduler/task_scheduler_impl.cc b/src/base/task/task_scheduler/task_scheduler_impl.cc
index 9a6c76d..89b5853 100644
--- a/src/base/task/task_scheduler/task_scheduler_impl.cc
+++ b/src/base/task/task_scheduler/task_scheduler_impl.cc
@@ -24,7 +24,6 @@
 #include "base/task/task_scheduler/task.h"
 #include "base/task/task_scheduler/task_tracker.h"
 #include "base/time/time.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 namespace internal {
diff --git a/src/base/task/task_scheduler/task_tracker_unittest.cc b/src/base/task/task_scheduler/task_tracker_unittest.cc
index f0fbfc2..392ea8b 100644
--- a/src/base/task/task_scheduler/task_tracker_unittest.cc
+++ b/src/base/task/task_scheduler/task_tracker_unittest.cc
@@ -1487,7 +1487,7 @@
   struct {
     const TaskTraits traits;
     const char* const expected_histogram;
-  } static CONSTEXPR kTests[] = {
+  } static constexpr kTests[] = {
       {{TaskPriority::BEST_EFFORT},
        "TaskScheduler.TaskLatencyMicroseconds.Test."
        "BackgroundTaskPriority"},
diff --git a/src/base/task/task_traits.h b/src/base/task/task_traits.h
index baa8366..97a87ad 100644
--- a/src/base/task/task_traits.h
+++ b/src/base/task/task_traits.h
@@ -169,7 +169,7 @@
                 trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>::value ||
                 trait_helpers::AreValidTraitsForExtension<ArgTypes...>::value>>
 #endif
-  CONSTEXPR TaskTraits(ArgTypes... args)
+  constexpr TaskTraits(ArgTypes... args)
 #if __cplusplus < 201402L
       :
 #else
@@ -212,34 +212,34 @@
   // the value from |right|. Note that extension traits are not merged: any
   // extension traits in |left| are discarded if extension traits are present in
   // |right|.
-  static CONSTEXPR TaskTraits Override(const TaskTraits& left,
+  static constexpr TaskTraits Override(const TaskTraits& left,
                                        const TaskTraits& right) {
     return TaskTraits(left, right);
   }
 
   // Returns true if the priority was set explicitly.
-  CONSTEXPR bool priority_set_explicitly() const {
+  constexpr bool priority_set_explicitly() const {
     return priority_set_explicitly_;
   }
 
   // Returns the priority of tasks with these traits.
-  CONSTEXPR TaskPriority priority() const { return priority_; }
+  constexpr TaskPriority priority() const { return priority_; }
 
   // Returns true if the shutdown behavior was set explicitly.
-  CONSTEXPR bool shutdown_behavior_set_explicitly() const {
+  constexpr bool shutdown_behavior_set_explicitly() const {
     return shutdown_behavior_set_explicitly_;
   }
 
   // Returns the shutdown behavior of tasks with these traits.
-  CONSTEXPR TaskShutdownBehavior shutdown_behavior() const {
+  constexpr TaskShutdownBehavior shutdown_behavior() const {
     return shutdown_behavior_;
   }
 
   // Returns true if tasks with these traits may block.
-  CONSTEXPR bool may_block() const { return may_block_; }
+  constexpr bool may_block() const { return may_block_; }
 
   // Returns true if tasks with these traits may use base/ sync primitives.
-  CONSTEXPR bool with_base_sync_primitives() const {
+  constexpr bool with_base_sync_primitives() const {
     return with_base_sync_primitives_;
   }
 
@@ -254,7 +254,7 @@
   }
 
  private:
-  CONSTEXPR TaskTraits(const TaskTraits& left, const TaskTraits& right)
+  constexpr TaskTraits(const TaskTraits& left, const TaskTraits& right)
       : extension_(right.extension_.extension_id !=
                            TaskTraitsExtensionStorage::kInvalidExtensionId
                        ? right.extension_
diff --git a/src/base/task/task_traits_details.h b/src/base/task/task_traits_details.h
index 6ed0d58..4d02c28 100644
--- a/src/base/task/task_traits_details.h
+++ b/src/base/task/task_traits_details.h
@@ -10,7 +10,6 @@
 #include <type_traits>
 #include <utility>
 
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 namespace trait_helpers {
@@ -183,21 +182,21 @@
 
 template <typename ArgType>
 struct BooleanTraitFilter : public BasicTraitFilter<bool> {
-  CONSTEXPR BooleanTraitFilter() { this->value = false; }
-  CONSTEXPR BooleanTraitFilter(ArgType) { this->value = true; }
+  constexpr BooleanTraitFilter() { this->value = false; }
+  constexpr BooleanTraitFilter(ArgType) { this->value = true; }
 };
 
 template <typename ArgType, ArgType DefaultValue>
 struct EnumTraitFilter : public BasicTraitFilter<ArgType> {
-  CONSTEXPR EnumTraitFilter() { this->value = DefaultValue; }
-  CONSTEXPR EnumTraitFilter(ArgType arg) { this->value = arg; }
+  constexpr EnumTraitFilter() { this->value = DefaultValue; }
+  constexpr EnumTraitFilter(ArgType arg) { this->value = arg; }
 };
 
 // Tests whether multiple given argtument types are all valid traits according
 // to the provided ValidTraits. To use, define a ValidTraits
 template <typename ArgType>
 struct RequiredEnumTraitFilter : public BasicTraitFilter<ArgType> {
-  CONSTEXPR RequiredEnumTraitFilter(ArgType arg) { this->value = arg; }
+  constexpr RequiredEnumTraitFilter(ArgType arg) { this->value = arg; }
 };
 
 #ifdef STARBOARD
diff --git a/src/base/task/task_traits_extension.h b/src/base/task/task_traits_extension.h
index d03d5b0..044a637 100644
--- a/src/base/task/task_traits_extension.h
+++ b/src/base/task/task_traits_extension.h
@@ -11,7 +11,6 @@
 
 #include "base/base_export.h"
 #include "base/task/task_traits_details.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
@@ -134,7 +133,7 @@
   inline constexpr TaskTraitsExtensionStorage(
       uint8_t extension_id_in,
       const std::array<uint8_t, kStorageSize>& data_in);
-  inline CONSTEXPR TaskTraitsExtensionStorage(
+  inline constexpr TaskTraitsExtensionStorage(
       uint8_t extension_id_in,
       std::array<uint8_t, kStorageSize>&& data_in);
 
@@ -172,7 +171,7 @@
     const std::array<uint8_t, kStorageSize>& data_in)
     : extension_id(extension_id_in), data(data_in) {}
 
-inline CONSTEXPR TaskTraitsExtensionStorage::TaskTraitsExtensionStorage(
+inline constexpr TaskTraitsExtensionStorage::TaskTraitsExtensionStorage(
     uint8_t extension_id_in,
     std::array<uint8_t, kStorageSize>&& data_in)
     : extension_id(extension_id_in), data(std::move(data_in)) {}
diff --git a/src/base/task/task_traits_extension_unittest.cc b/src/base/task/task_traits_extension_unittest.cc
index 394cdbe..59d295e 100644
--- a/src/base/task/task_traits_extension_unittest.cc
+++ b/src/base/task/task_traits_extension_unittest.cc
@@ -5,13 +5,12 @@
 #include "base/task/task_traits.h"
 
 #include "base/task/test_task_traits_extension.h"
-#include "nb/cpp14oncpp11.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
 TEST(TaskTraitsExtensionTest, NoExtension) {
-  CONSTEXPR TaskTraits traits = {};
+  constexpr TaskTraits traits = {};
 
   EXPECT_EQ(traits.extension_id(),
             TaskTraitsExtensionStorage::kInvalidExtensionId);
@@ -20,7 +19,7 @@
 #if !defined(STARBOARD)
 // Cobalt does not support task traits with extension yet.
 TEST(TaskTraitsExtensionTest, CreateWithOneExtensionTrait) {
-  CONSTEXPR TaskTraits traits = {TestExtensionEnumTrait::kB};
+  constexpr TaskTraits traits = {TestExtensionEnumTrait::kB};
 
   EXPECT_EQ(traits.GetExtension<TestTaskTraitsExtension>().enum_trait(),
             TestExtensionEnumTrait::kB);
@@ -28,7 +27,7 @@
 }
 
 TEST(TaskTraitsExtensionTest, CreateWithMultipleExtensionTraits) {
-  CONSTEXPR TaskTraits traits = {TestExtensionEnumTrait::kB,
+  constexpr TaskTraits traits = {TestExtensionEnumTrait::kB,
                                  TestExtensionBoolTrait()};
 
   EXPECT_EQ(traits.GetExtension<TestTaskTraitsExtension>().enum_trait(),
@@ -37,7 +36,7 @@
 }
 
 TEST(TaskTraitsExtensionTest, CreateWithBaseAndExtensionTraits) {
-  CONSTEXPR TaskTraits traits = {TaskPriority::USER_BLOCKING,
+  constexpr TaskTraits traits = {TaskPriority::USER_BLOCKING,
                                  TestExtensionEnumTrait::kC,
                                  TestExtensionBoolTrait()};
 
diff --git a/src/base/task/task_traits_unittest.cc b/src/base/task/task_traits_unittest.cc
index 41e76e8..95d24e4 100644
--- a/src/base/task/task_traits_unittest.cc
+++ b/src/base/task/task_traits_unittest.cc
@@ -3,14 +3,13 @@
 // found in the LICENSE file.
 
 #include "base/task/task_traits.h"
-#include "nb/cpp14oncpp11.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
 TEST(TaskTraitsTest, Default) {
-  CONSTEXPR TaskTraits traits = {};
+  constexpr TaskTraits traits = {};
   EXPECT_FALSE(traits.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_VISIBLE, traits.priority());
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN, traits.shutdown_behavior());
@@ -19,7 +18,7 @@
 }
 
 TEST(TaskTraitsTest, TaskPriority) {
-  CONSTEXPR TaskTraits traits = {TaskPriority::BEST_EFFORT};
+  constexpr TaskTraits traits = {TaskPriority::BEST_EFFORT};
   EXPECT_TRUE(traits.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::BEST_EFFORT, traits.priority());
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN, traits.shutdown_behavior());
@@ -28,7 +27,7 @@
 }
 
 TEST(TaskTraitsTest, TaskShutdownBehavior) {
-  CONSTEXPR TaskTraits traits = {TaskShutdownBehavior::BLOCK_SHUTDOWN};
+  constexpr TaskTraits traits = {TaskShutdownBehavior::BLOCK_SHUTDOWN};
   EXPECT_FALSE(traits.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_VISIBLE, traits.priority());
   EXPECT_EQ(TaskShutdownBehavior::BLOCK_SHUTDOWN, traits.shutdown_behavior());
@@ -37,7 +36,7 @@
 }
 
 TEST(TaskTraitsTest, MayBlock) {
-  CONSTEXPR TaskTraits traits = {MayBlock()};
+  constexpr TaskTraits traits = {MayBlock()};
   EXPECT_FALSE(traits.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_VISIBLE, traits.priority());
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN, traits.shutdown_behavior());
@@ -46,7 +45,7 @@
 }
 
 TEST(TaskTraitsTest, WithBaseSyncPrimitives) {
-  CONSTEXPR TaskTraits traits = {WithBaseSyncPrimitives()};
+  constexpr TaskTraits traits = {WithBaseSyncPrimitives()};
   EXPECT_FALSE(traits.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_VISIBLE, traits.priority());
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN, traits.shutdown_behavior());
@@ -55,7 +54,7 @@
 }
 
 TEST(TaskTraitsTest, MultipleTraits) {
-  CONSTEXPR TaskTraits traits = {TaskPriority::BEST_EFFORT,
+  constexpr TaskTraits traits = {TaskPriority::BEST_EFFORT,
                                  TaskShutdownBehavior::BLOCK_SHUTDOWN,
                                  MayBlock(), WithBaseSyncPrimitives()};
   EXPECT_TRUE(traits.priority_set_explicitly());
@@ -66,10 +65,10 @@
 }
 
 TEST(TaskTraitsTest, Copy) {
-  CONSTEXPR TaskTraits traits = {TaskPriority::BEST_EFFORT,
+  constexpr TaskTraits traits = {TaskPriority::BEST_EFFORT,
                                  TaskShutdownBehavior::BLOCK_SHUTDOWN,
                                  MayBlock(), WithBaseSyncPrimitives()};
-  CONSTEXPR TaskTraits traits_copy(traits);
+  constexpr TaskTraits traits_copy(traits);
   EXPECT_EQ(traits.priority_set_explicitly(),
             traits_copy.priority_set_explicitly());
   EXPECT_EQ(traits.priority(), traits_copy.priority());
@@ -80,9 +79,9 @@
 }
 
 TEST(TaskTraitsTest, OverridePriority) {
-  CONSTEXPR TaskTraits left = {TaskPriority::BEST_EFFORT};
-  CONSTEXPR TaskTraits right = {TaskPriority::USER_BLOCKING};
-  CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+  constexpr TaskTraits left = {TaskPriority::BEST_EFFORT};
+  constexpr TaskTraits right = {TaskPriority::USER_BLOCKING};
+  constexpr TaskTraits overridden = TaskTraits::Override(left, right);
   EXPECT_TRUE(overridden.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_BLOCKING, overridden.priority());
   EXPECT_FALSE(overridden.shutdown_behavior_set_explicitly());
@@ -93,9 +92,9 @@
 }
 
 TEST(TaskTraitsTest, OverrideShutdownBehavior) {
-  CONSTEXPR TaskTraits left = {TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
-  CONSTEXPR TaskTraits right = {TaskShutdownBehavior::BLOCK_SHUTDOWN};
-  CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+  constexpr TaskTraits left = {TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
+  constexpr TaskTraits right = {TaskShutdownBehavior::BLOCK_SHUTDOWN};
+  constexpr TaskTraits overridden = TaskTraits::Override(left, right);
   EXPECT_FALSE(overridden.priority_set_explicitly());
   EXPECT_EQ(TaskPriority::USER_VISIBLE, overridden.priority());
   EXPECT_TRUE(overridden.shutdown_behavior_set_explicitly());
@@ -107,9 +106,9 @@
 
 TEST(TaskTraitsTest, OverrideMayBlock) {
   {
-    CONSTEXPR TaskTraits left = {MayBlock()};
-    CONSTEXPR TaskTraits right = {};
-    CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+    constexpr TaskTraits left = {MayBlock()};
+    constexpr TaskTraits right = {};
+    constexpr TaskTraits overridden = TaskTraits::Override(left, right);
     EXPECT_FALSE(overridden.priority_set_explicitly());
     EXPECT_EQ(TaskPriority::USER_VISIBLE, overridden.priority());
     EXPECT_FALSE(overridden.shutdown_behavior_set_explicitly());
@@ -119,9 +118,9 @@
     EXPECT_FALSE(overridden.with_base_sync_primitives());
   }
   {
-    CONSTEXPR TaskTraits left = {};
-    CONSTEXPR TaskTraits right = {MayBlock()};
-    CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+    constexpr TaskTraits left = {};
+    constexpr TaskTraits right = {MayBlock()};
+    constexpr TaskTraits overridden = TaskTraits::Override(left, right);
     EXPECT_FALSE(overridden.priority_set_explicitly());
     EXPECT_EQ(TaskPriority::USER_VISIBLE, overridden.priority());
     EXPECT_FALSE(overridden.shutdown_behavior_set_explicitly());
@@ -134,9 +133,9 @@
 
 TEST(TaskTraitsTest, OverrideWithBaseSyncPrimitives) {
   {
-    CONSTEXPR TaskTraits left = {WithBaseSyncPrimitives()};
-    CONSTEXPR TaskTraits right = {};
-    CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+    constexpr TaskTraits left = {WithBaseSyncPrimitives()};
+    constexpr TaskTraits right = {};
+    constexpr TaskTraits overridden = TaskTraits::Override(left, right);
     EXPECT_FALSE(overridden.priority_set_explicitly());
     EXPECT_EQ(TaskPriority::USER_VISIBLE, overridden.priority());
     EXPECT_FALSE(overridden.shutdown_behavior_set_explicitly());
@@ -146,9 +145,9 @@
     EXPECT_TRUE(overridden.with_base_sync_primitives());
   }
   {
-    CONSTEXPR TaskTraits left = {};
-    CONSTEXPR TaskTraits right = {WithBaseSyncPrimitives()};
-    CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+    constexpr TaskTraits left = {};
+    constexpr TaskTraits right = {WithBaseSyncPrimitives()};
+    constexpr TaskTraits overridden = TaskTraits::Override(left, right);
     EXPECT_FALSE(overridden.priority_set_explicitly());
     EXPECT_EQ(TaskPriority::USER_VISIBLE, overridden.priority());
     EXPECT_FALSE(overridden.shutdown_behavior_set_explicitly());
@@ -160,11 +159,11 @@
 }
 
 TEST(TaskTraitsTest, OverrideMultipleTraits) {
-  CONSTEXPR TaskTraits left = {MayBlock(), TaskPriority::BEST_EFFORT,
+  constexpr TaskTraits left = {MayBlock(), TaskPriority::BEST_EFFORT,
                                TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
-  CONSTEXPR TaskTraits right = {WithBaseSyncPrimitives(),
+  constexpr TaskTraits right = {WithBaseSyncPrimitives(),
                                 TaskPriority::USER_BLOCKING};
-  CONSTEXPR TaskTraits overridden = TaskTraits::Override(left, right);
+  constexpr TaskTraits overridden = TaskTraits::Override(left, right);
   EXPECT_TRUE(overridden.priority_set_explicitly());
   EXPECT_EQ(right.priority(), overridden.priority());
   EXPECT_TRUE(overridden.shutdown_behavior_set_explicitly());
diff --git a/src/base/task/test_task_traits_extension.h b/src/base/task/test_task_traits_extension.h
index c5b6a99..738846c 100644
--- a/src/base/task/test_task_traits_extension.h
+++ b/src/base/task/test_task_traits_extension.h
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/task/task_traits.h"
-#include "nb/cpp14oncpp11.h"
 
 namespace base {
 
@@ -43,7 +42,7 @@
         bool_trait_(trait_helpers::GetTraitFromArgList<TestExtensionBoolFilter>(
             args...)) {}
 
-  CONSTEXPR TaskTraitsExtensionStorage Serialize() const {
+  constexpr TaskTraitsExtensionStorage Serialize() const {
     return {kExtensionId, {{static_cast<uint8_t>(enum_trait_), bool_trait_}}};
   }
 
diff --git a/src/base/template_util.h b/src/base/template_util.h
index 8fea7be..b62396a 100644
--- a/src/base/template_util.h
+++ b/src/base/template_util.h
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 
 // Some versions of libstdc++ have partial support for type_traits, but misses
 // a smaller subset while removing some of the older non-standard stuff. Assume
diff --git a/src/base/test/generate_fontconfig_caches.cc b/src/base/test/generate_fontconfig_caches.cc
index 2a4a2ec..f4acab2 100644
--- a/src/base/test/generate_fontconfig_caches.cc
+++ b/src/base/test/generate_fontconfig_caches.cc
@@ -34,7 +34,7 @@
   base::FilePath uuid_file_path =
       dir_module.Append("test_fonts").Append(".uuid");
   const char uuid[] = "df1acc8c-39d5-4a8b-8507-b1a7396ac3ac";
-  WriteFile(uuid_file_path, uuid, SbStringGetLength(uuid));
+  WriteFile(uuid_file_path, uuid, strlen(uuid));
 
   // fontconfig writes the mtime of the test_fonts directory into the cache. It
   // presumably checks this later to ensure that the cache is still up to date.
diff --git a/src/base/test/launcher/test_launcher.cc b/src/base/test/launcher/test_launcher.cc
index 0309580..244239b 100644
--- a/src/base/test/launcher/test_launcher.cc
+++ b/src/base/test/launcher/test_launcher.cc
@@ -631,7 +631,7 @@
   CHECK_EQ(0, pipe(g_shutdown_pipe));
 
   struct sigaction action;
-  SbMemorySet(&action, 0, sizeof(action));
+  memset(&action, 0, sizeof(action));
   sigemptyset(&action.sa_mask);
   action.sa_handler = &ShutdownPipeSignalHandler;
 
diff --git a/src/base/test/test_discardable_memory_allocator.cc b/src/base/test/test_discardable_memory_allocator.cc
index 6ab854f..57f3661 100644
--- a/src/base/test/test_discardable_memory_allocator.cc
+++ b/src/base/test/test_discardable_memory_allocator.cc
@@ -32,7 +32,7 @@
     is_locked_ = false;
     // Force eviction to catch clients not correctly checking the return value
     // of Lock().
-    SbMemorySet(data_.get(), 0, size_);
+    memset(data_.get(), 0, size_);
   }
 
   void* data() const override {
diff --git a/src/base/test/test_file_util_win.cc b/src/base/test/test_file_util_win.cc
index b1be605..557f062 100644
--- a/src/base/test/test_file_util_win.cc
+++ b/src/base/test/test_file_util_win.cc
@@ -50,7 +50,7 @@
   *length = sizeof(PSECURITY_DESCRIPTOR) + dacl->AclSize;
   PermissionInfo* info = reinterpret_cast<PermissionInfo*>(new char[*length]);
   info->security_descriptor = security_descriptor;
-  SbMemoryCopy(&info->dacl, dacl, dacl->AclSize);
+  memcpy(&info->dacl, dacl, dacl->AclSize);
 
   return info;
 }
diff --git a/src/base/test/trace_to_file.cc b/src/base/test/trace_to_file.cc
index 7f66784..673f187 100644
--- a/src/base/test/trace_to_file.cc
+++ b/src/base/test/trace_to_file.cc
@@ -61,12 +61,12 @@
 
 void TraceToFile::WriteFileHeader() {
   const char str[] = "{\"traceEvents\": [";
-  WriteFile(path_, str, static_cast<int>(SbStringGetLength(str)));
+  WriteFile(path_, str, static_cast<int>(strlen(str)));
 }
 
 void TraceToFile::AppendFileFooter() {
   const char str[] = "]}";
-  AppendToFile(path_, str, static_cast<int>(SbStringGetLength(str)));
+  AppendToFile(path_, str, static_cast<int>(strlen(str)));
 }
 
 void TraceToFile::TraceOutputCallback(const std::string& data) {
diff --git a/src/base/third_party/dmg_fp/dtoa.cc b/src/base/third_party/dmg_fp/dtoa.cc
index e7d697c..a32694d 100644
--- a/src/base/third_party/dmg_fp/dtoa.cc
+++ b/src/base/third_party/dmg_fp/dtoa.cc
@@ -622,7 +622,7 @@
 	}
 
 #define Bcopy(x, y)                              \
-  SbMemoryCopy((char*)&x->sign, (char*)&y->sign, \
+  memcpy((char*)&x->sign, (char*)&y->sign, \
                y->wds * sizeof(Long) + 2 * sizeof(int))
 
         static Bigint* multadd
@@ -1824,8 +1824,8 @@
 	if (!(s0 = decimalpoint_cache)) {
 		s0 = (unsigned char*)localeconv()->decimal_point;
                 if ((decimalpoint_cache = (unsigned char*)MALLOC(
-                         SbStringGetLength((CONST char*)s0) + 1))) {
-                  SbStringCopyUnsafe((char*)decimalpoint_cache,
+                         strlen((CONST char*)s0) + 1))) {
+                  strcpy((char*)decimalpoint_cache,
                                      (CONST char*)s0);
                   s0 = decimalpoint_cache;
 			}
diff --git a/src/base/third_party/libevent/evrpc.h b/src/base/third_party/libevent/evrpc.h
index c88da3a..64e6d35 100644
--- a/src/base/third_party/libevent/evrpc.h
+++ b/src/base/third_party/libevent/evrpc.h
@@ -208,7 +208,7 @@
         (int (*)(void*, struct evbuffer*))rplystruct##_unmarshal;             \
     return (evrpc_make_request(ctx));                                         \
   error:                                                                      \
-    SbMemorySet(&status, 0, sizeof(status));                                  \
+    memset(&status, 0, sizeof(status));                                  \
     status.error = EVRPC_STATUS_ERR_UNSTARTED;                                \
     (*(cb))(&status, request, reply, cbarg);                                  \
     return (-1);                                                              \
diff --git a/src/base/third_party/nspr/prtime.cc b/src/base/third_party/nspr/prtime.cc
index 0a4da71..982fcad 100644
--- a/src/base/third_party/nspr/prtime.cc
+++ b/src/base/third_party/nspr/prtime.cc
@@ -1112,7 +1112,7 @@
   if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX)
       return PR_FAILURE;
 
-  SbMemorySet(result, 0, sizeof(*result));
+  memset(result, 0, sizeof(*result));
   if (usec != -1)
         result->tm_usec = usec;
   if (sec != -1)
diff --git a/src/base/threading/scoped_blocking_call_unittest.cc b/src/base/threading/scoped_blocking_call_unittest.cc
index 3ea9950..5e030f3 100644
--- a/src/base/threading/scoped_blocking_call_unittest.cc
+++ b/src/base/threading/scoped_blocking_call_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "base/macros.h"
 #include "base/test/gtest_util.h"
-#include "nb/cpp14oncpp11.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/src/base/threading/thread_local_storage.cc b/src/base/threading/thread_local_storage.cc
index b2cf345..f1d5324 100644
--- a/src/base/threading/thread_local_storage.cc
+++ b/src/base/threading/thread_local_storage.cc
@@ -200,13 +200,13 @@
   // our service is in place. (i.e., don't even call new until after we're
   // setup)
   TlsVectorEntry stack_allocated_tls_data[kThreadLocalStorageSize];
-  SbMemorySet(stack_allocated_tls_data, 0, sizeof(stack_allocated_tls_data));
+  memset(stack_allocated_tls_data, 0, sizeof(stack_allocated_tls_data));
   // Ensure that any rentrant calls change the temp version.
   PlatformThreadLocalStorage::SetTLSValue(key, stack_allocated_tls_data);
 
   // Allocate an array to store our data.
   TlsVectorEntry* tls_data = new TlsVectorEntry[kThreadLocalStorageSize];
-  SbMemoryCopy(tls_data, stack_allocated_tls_data,
+  memcpy(tls_data, stack_allocated_tls_data,
                sizeof(stack_allocated_tls_data));
   PlatformThreadLocalStorage::SetTLSValue(key, tls_data);
   return tls_data;
@@ -235,7 +235,7 @@
   // we have called all g_tls_metadata destructors. (i.e., don't even call
   // delete[] after we're done with destructors.)
   TlsVectorEntry stack_allocated_tls_data[kThreadLocalStorageSize];
-  SbMemoryCopy(stack_allocated_tls_data, tls_data,
+  memcpy(stack_allocated_tls_data, tls_data,
                sizeof(stack_allocated_tls_data));
   // Ensure that any re-entrant calls change the temp version.
   PlatformThreadLocalStorage::TLSKey key =
@@ -248,7 +248,7 @@
   TlsMetadata tls_metadata[kThreadLocalStorageSize];
   {
     base::AutoLock auto_lock(*GetTLSMetadataLock());
-    SbMemoryCopy(tls_metadata, g_tls_metadata, sizeof(g_tls_metadata));
+    memcpy(tls_metadata, g_tls_metadata, sizeof(g_tls_metadata));
   }
 
   int remaining_attempts = kMaxDestructorIterations;
diff --git a/src/base/time/time.h b/src/base/time/time.h
index 88d1238..7cc797e 100644
--- a/src/base/time/time.h
+++ b/src/base/time/time.h
@@ -61,7 +61,6 @@
 #include "base/logging.h"
 #include "base/numerics/safe_math.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 
 #if defined(STARBOARD)
 #include "starboard/time.h"
@@ -163,7 +162,7 @@
   constexpr int64_t ToInternalValue() const { return delta_; }
 
   // Returns the magnitude (absolute value) of this TimeDelta.
-  CONSTEXPR TimeDelta magnitude() const {
+  constexpr TimeDelta magnitude() const {
     // Some toolchains provide an incomplete C++11 implementation and lack an
     // int64_t overload for std::abs().  The following is a simple branchless
     // implementation:
@@ -242,7 +241,7 @@
     return TimeDelta(std::numeric_limits<int64_t>::max());
   }
   template <typename T>
-  CONSTEXPR TimeDelta operator/(T a) const {
+  constexpr TimeDelta operator/(T a) const {
     CheckedNumeric<int64_t> rv(delta_);
     rv /= a;
     if (rv.IsValid())
@@ -258,7 +257,7 @@
     return *this = (*this * a);
   }
   template <typename T>
-  CONSTEXPR TimeDelta& operator/=(T a) {
+  constexpr TimeDelta& operator/=(T a) {
     return *this = (*this / a);
   }
 
diff --git a/src/base/time/time_unittest.cc b/src/base/time/time_unittest.cc
index b29019e..eb0dcd1 100644
--- a/src/base/time/time_unittest.cc
+++ b/src/base/time/time_unittest.cc
@@ -18,7 +18,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
-#include "nb/cpp14oncpp11.h"
 #if defined(STARBOARD)
 #include "base/test/time_helpers.h"
 #endif  // defined(STARBOARD)
@@ -1288,16 +1287,16 @@
 
 TEST(TimeDelta, Magnitude) {
   constexpr int64_t zero = 0;
-  STATIC_ASSERT(TimeDelta::FromMicroseconds(zero) ==
+  static_assert(TimeDelta::FromMicroseconds(zero) ==
                     TimeDelta::FromMicroseconds(zero).magnitude(),
                 "");
 
   constexpr int64_t one = 1;
   constexpr int64_t negative_one = -1;
-  STATIC_ASSERT(TimeDelta::FromMicroseconds(one) ==
+  static_assert(TimeDelta::FromMicroseconds(one) ==
                     TimeDelta::FromMicroseconds(one).magnitude(),
                 "");
-  STATIC_ASSERT(TimeDelta::FromMicroseconds(one) ==
+  static_assert(TimeDelta::FromMicroseconds(one) ==
                     TimeDelta::FromMicroseconds(negative_one).magnitude(),
                 "");
 
@@ -1305,11 +1304,11 @@
       std::numeric_limits<int64_t>::max() - 1;
   constexpr int64_t min_int64_plus_two =
       std::numeric_limits<int64_t>::min() + 2;
-  STATIC_ASSERT(
+  static_assert(
       TimeDelta::FromMicroseconds(max_int64_minus_one) ==
           TimeDelta::FromMicroseconds(max_int64_minus_one).magnitude(),
       "");
-  STATIC_ASSERT(TimeDelta::FromMicroseconds(max_int64_minus_one) ==
+  static_assert(TimeDelta::FromMicroseconds(max_int64_minus_one) ==
                     TimeDelta::FromMicroseconds(min_int64_plus_two).magnitude(),
                 "");
 }
@@ -1424,12 +1423,12 @@
   constexpr double d = 0.5;
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) * d));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) / d),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) *= d));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) /= d),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
@@ -1438,12 +1437,12 @@
   constexpr float f = 0.5;
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) * f));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) / f),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) *= f));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) /= f),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
@@ -1452,12 +1451,12 @@
   constexpr int i = 2;
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) * i));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) / i),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) *= i));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) /= i),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
@@ -1466,12 +1465,12 @@
   constexpr int64_t i64 = 2;
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) * i64));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) / i64),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) *= i64));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) /= i64),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
@@ -1479,12 +1478,12 @@
 
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) * 0.5));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) / 0.5),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
             (TimeDelta::FromMilliseconds(1000) *= 0.5));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(2000) ==
+  static_assert(TimeDelta::FromMilliseconds(2000) ==
                     (TimeDelta::FromMilliseconds(1000) /= 0.5),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(500),
@@ -1492,12 +1491,12 @@
 
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) * 2));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) / 2),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
             (TimeDelta::FromMilliseconds(1000) *= 2));
-  STATIC_ASSERT(TimeDelta::FromMilliseconds(500) ==
+  static_assert(TimeDelta::FromMilliseconds(500) ==
                     (TimeDelta::FromMilliseconds(1000) /= 2),
                 "");
   EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
@@ -1597,7 +1596,7 @@
   EXPECT_EQ(kOneSecond, (ticks_now + kOneSecond) - ticks_now);
 }
 
-CONSTEXPR TimeTicks TestTimeTicksConstexprCopyAssignment() {
+constexpr TimeTicks TestTimeTicksConstexprCopyAssignment() {
   TimeTicks a = TimeTicks::FromInternalValue(12345);
   TimeTicks b;
   b = a;
@@ -1618,12 +1617,12 @@
   static_assert(a.ToInternalValue() == b.ToInternalValue(), "");
 
   // Copy assignment.
-  STATIC_ASSERT(a.ToInternalValue() ==
+  static_assert(a.ToInternalValue() ==
                     TestTimeTicksConstexprCopyAssignment().ToInternalValue(),
                 "");
 }
 
-CONSTEXPR ThreadTicks TestThreadTicksConstexprCopyAssignment() {
+constexpr ThreadTicks TestThreadTicksConstexprCopyAssignment() {
   ThreadTicks a = ThreadTicks::FromInternalValue(12345);
   ThreadTicks b;
   b = a;
@@ -1644,12 +1643,12 @@
   static_assert(a.ToInternalValue() == b.ToInternalValue(), "");
 
   // Copy assignment.
-  STATIC_ASSERT(a.ToInternalValue() ==
+  static_assert(a.ToInternalValue() ==
                     TestThreadTicksConstexprCopyAssignment().ToInternalValue(),
                 "");
 }
 
-CONSTEXPR TimeDelta TestTimeDeltaConstexprCopyAssignment() {
+constexpr TimeDelta TestTimeDeltaConstexprCopyAssignment() {
   TimeDelta a = TimeDelta::FromSeconds(1);
   TimeDelta b;
   b = a;
@@ -1670,7 +1669,7 @@
   static_assert(a == b, "");
 
   // Copy assignment.
-  STATIC_ASSERT(a == TestTimeDeltaConstexprCopyAssignment(), "");
+  static_assert(a == TestTimeDeltaConstexprCopyAssignment(), "");
 }
 
 TEST(TimeDeltaLogging, DCheckEqCompiles) {
diff --git a/src/base/trace_event/blame_context.cc b/src/base/trace_event/blame_context.cc
index fdde1ac..cc9a6fe 100644
--- a/src/base/trace_event/blame_context.cc
+++ b/src/base/trace_event/blame_context.cc
@@ -28,7 +28,7 @@
       parent_id_(parent_context ? parent_context->id() : 0),
       category_group_enabled_(nullptr),
       weak_factory_(this) {
-  DCHECK(!parent_context || !SbStringCompareAll(name_, parent_context->name()))
+  DCHECK(!parent_context || !strcmp(name_, parent_context->name()))
       << "Parent blame context must have the same name";
 }
 
diff --git a/src/base/trace_event/cfi_backtrace_android.cc b/src/base/trace_event/cfi_backtrace_android.cc
index d128573..eb6e190 100644
--- a/src/base/trace_event/cfi_backtrace_android.cc
+++ b/src/base/trace_event/cfi_backtrace_android.cc
@@ -168,7 +168,7 @@
   static constexpr size_t kUnwIndexRowSize =
       sizeof(*unw_index_function_col_) + sizeof(*unw_index_indices_col_);
   size_t unw_index_size = 0;
-  SbMemoryCopy(&unw_index_size, cfi_mmap_->data(), sizeof(unw_index_size));
+  memcpy(&unw_index_size, cfi_mmap_->data(), sizeof(unw_index_size));
   DCHECK_EQ(0u, unw_index_size % kUnwIndexRowSize);
   // UNW_INDEX table starts after 4 bytes.
   unw_index_function_col_ =
@@ -223,7 +223,7 @@
     // SP_prev = SP_cur + cfa_offset and
     // PC_prev = * (SP_prev - ra_offset).
     sp = sp + cfi.cfa_offset;
-    SbMemoryCopy(&pc, reinterpret_cast<uintptr_t*>(sp - cfi.ra_offset),
+    memcpy(&pc, reinterpret_cast<uintptr_t*>(sp - cfi.ra_offset),
                  sizeof(uintptr_t));
   }
   return depth;
@@ -275,7 +275,7 @@
   const uint16_t* unwind_data = unw_data_start_addr_ + index;
   // The value of first 2 bytes is the CFI data row count for the function.
   uint16_t row_count = 0;
-  SbMemoryCopy(&row_count, unwind_data, sizeof(row_count));
+  memcpy(&row_count, unwind_data, sizeof(row_count));
   // And the actual CFI rows start after 2 bytes from the |unwind_data|. Cast
   // the data into an array of CFIUnwindDataRow since the struct is designed to
   // represent each row. We should be careful to read only |row_count| number of
@@ -289,7 +289,7 @@
   uint16_t ra_offset = 0;
   for (uint16_t i = 0; i < row_count; ++i) {
     CFIUnwindDataRow row;
-    SbMemoryCopy(&row, function_data + i, sizeof(CFIUnwindDataRow));
+    memcpy(&row, function_data + i, sizeof(CFIUnwindDataRow));
     // The return address of the function is the instruction that is not yet
     // been executed. The cfi row specifies the unwind info before executing the
     // given instruction. If the given address is equal to the instruction
diff --git a/src/base/trace_event/memory_dump_manager.cc b/src/base/trace_event/memory_dump_manager.cc
index 6e317a3..8437654 100644
--- a/src/base/trace_event/memory_dump_manager.cc
+++ b/src/base/trace_event/memory_dump_manager.cc
@@ -448,7 +448,7 @@
   // crashes while invoking dump after a |dump_provider| is not unregistered
   // in safe way.
   char provider_name_for_debugging[16];
-  SbStringCopy(provider_name_for_debugging, mdpinfo->name,
+  strncpy(provider_name_for_debugging, mdpinfo->name,
                sizeof(provider_name_for_debugging) - 1);
   provider_name_for_debugging[sizeof(provider_name_for_debugging) - 1] = '\0';
   base::debug::Alias(provider_name_for_debugging);
diff --git a/src/base/trace_event/memory_infra_background_whitelist.cc b/src/base/trace_event/memory_infra_background_whitelist.cc
index 19bfe83..435eef6 100644
--- a/src/base/trace_event/memory_infra_background_whitelist.cc
+++ b/src/base/trace_event/memory_infra_background_whitelist.cc
@@ -380,14 +380,14 @@
 bool IsMemoryAllocatorDumpNameWhitelisted(const std::string& name) {
   // Global dumps are explicitly whitelisted for background use.
   if (base::StartsWith(name, "global/", CompareCase::SENSITIVE)) {
-    for (size_t i = SbStringGetLength("global/"); i < name.size(); i++)
+    for (size_t i = strlen("global/"); i < name.size(); i++)
       if (!base::IsHexDigit(name[i]))
         return false;
     return true;
   }
 
   if (base::StartsWith(name, "shared_memory/", CompareCase::SENSITIVE)) {
-    for (size_t i = SbStringGetLength("shared_memory/"); i < name.size(); i++)
+    for (size_t i = strlen("shared_memory/"); i < name.size(); i++)
       if (!base::IsHexDigit(name[i]))
         return false;
     return true;
diff --git a/src/base/trace_event/memory_usage_estimator.h b/src/base/trace_event/memory_usage_estimator.h
index 8692b91..5a47521 100644
--- a/src/base/trace_event/memory_usage_estimator.h
+++ b/src/base/trace_event/memory_usage_estimator.h
@@ -29,7 +29,6 @@
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/template_util.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 // Composable memory usage estimators.
@@ -276,7 +275,7 @@
 #endif
 
 template <class I, template <class...> class... Containers>
-CONSTEXPR bool OneOfContainersComplexIterators() {
+constexpr bool OneOfContainersComplexIterators() {
   // We are forced to create a temporary variable to workaround a compilation
   // error in msvs.
   const bool all_tests[] = {
diff --git a/src/base/trace_event/memory_usage_estimator_unittest.cc b/src/base/trace_event/memory_usage_estimator_unittest.cc
index 0f3451b..36911e8 100644
--- a/src/base/trace_event/memory_usage_estimator_unittest.cc
+++ b/src/base/trace_event/memory_usage_estimator_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -247,23 +246,23 @@
     virtual void method() = 0;
   };
 
-  STATIC_ASSERT(
+  static_assert(
       internal::IsStandardContainerComplexIterator<std::list<int>::iterator>(),
       "");
-  STATIC_ASSERT(internal::IsStandardContainerComplexIterator<
+  static_assert(internal::IsStandardContainerComplexIterator<
                     std::list<int>::const_iterator>(),
                 "");
-  STATIC_ASSERT(internal::IsStandardContainerComplexIterator<
+  static_assert(internal::IsStandardContainerComplexIterator<
                     std::list<int>::reverse_iterator>(),
                 "");
-  STATIC_ASSERT(internal::IsStandardContainerComplexIterator<
+  static_assert(internal::IsStandardContainerComplexIterator<
                     std::list<int>::const_reverse_iterator>(),
                 "");
 #ifndef STARBOARD
   // TODO: Non-conforming compilers do not compile with int as iterator.
-  STATIC_ASSERT(!internal::IsStandardContainerComplexIterator<int>(), "");
+  static_assert(!internal::IsStandardContainerComplexIterator<int>(), "");
 #endif
-  STATIC_ASSERT(!internal::IsStandardContainerComplexIterator<abstract*>(), "");
+  static_assert(!internal::IsStandardContainerComplexIterator<abstract*>(), "");
 }
 
 }  // namespace trace_event
diff --git a/src/base/trace_event/process_memory_dump_unittest.cc b/src/base/trace_event/process_memory_dump_unittest.cc
index b47a509..5ce7590 100644
--- a/src/base/trace_event/process_memory_dump_unittest.cc
+++ b/src/base/trace_event/process_memory_dump_unittest.cc
@@ -488,7 +488,7 @@
   // Allocate few page of dirty memory and check if it is resident.
   const size_t size1 = 5 * page_size;
   void* memory1 = Map(size1);
-  SbMemorySet(memory1, 0, size1);
+  memset(memory1, 0, size1);
   size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1, size1);
   ASSERT_EQ(res1, size1);
   Unmap(memory1, size1);
@@ -496,7 +496,7 @@
   // Allocate a large memory segment (> 8Mib).
   const size_t kVeryLargeMemorySize = 15 * 1024 * 1024;
   void* memory2 = Map(kVeryLargeMemorySize);
-  SbMemorySet(memory2, 0, kVeryLargeMemorySize);
+  memset(memory2, 0, kVeryLargeMemorySize);
   size_t res2 =
       ProcessMemoryDump::CountResidentBytes(memory2, kVeryLargeMemorySize);
   ASSERT_EQ(res2, kVeryLargeMemorySize);
@@ -524,7 +524,7 @@
   const size_t size1 = 5 * page_size;
   SharedMemory shared_memory1;
   shared_memory1.CreateAndMapAnonymous(size1);
-  SbMemorySet(shared_memory1.memory(), 0, size1);
+  memset(shared_memory1.memory(), 0, size1);
   base::Optional<size_t> res1 =
       ProcessMemoryDump::CountResidentBytesInSharedMemory(
           shared_memory1.memory(), shared_memory1.mapped_size());
@@ -537,7 +537,7 @@
   const size_t kVeryLargeMemorySize = 15 * 1024 * 1024;
   SharedMemory shared_memory2;
   shared_memory2.CreateAndMapAnonymous(kVeryLargeMemorySize);
-  SbMemorySet(shared_memory2.memory(), 0, kVeryLargeMemorySize);
+  memset(shared_memory2.memory(), 0, kVeryLargeMemorySize);
   base::Optional<size_t> res2 =
       ProcessMemoryDump::CountResidentBytesInSharedMemory(
           shared_memory2.memory(), shared_memory2.mapped_size());
@@ -550,7 +550,7 @@
   const size_t kTouchedMemorySize = 7 * 1024 * 1024;
   SharedMemory shared_memory3;
   shared_memory3.CreateAndMapAnonymous(kVeryLargeMemorySize);
-  SbMemorySet(shared_memory3.memory(), 0, kTouchedMemorySize);
+  memset(shared_memory3.memory(), 0, kTouchedMemorySize);
   base::Optional<size_t> res3 =
       ProcessMemoryDump::CountResidentBytesInSharedMemory(
           shared_memory3.memory(), shared_memory3.mapped_size());
diff --git a/src/base/trace_event/trace_config_category_filter.cc b/src/base/trace_event/trace_config_category_filter.cc
index 16c3da5..849191c 100644
--- a/src/base/trace_event/trace_config_category_filter.cc
+++ b/src/base/trace_event/trace_config_category_filter.cc
@@ -181,7 +181,7 @@
     std::string category;
     if (!included_list.GetString(i, &category))
       continue;
-    if (category.compare(0, SbStringGetLength(TRACE_DISABLED_BY_DEFAULT("")),
+    if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
                          TRACE_DISABLED_BY_DEFAULT("")) == 0) {
       disabled_categories_.push_back(category);
     } else {
diff --git a/src/base/trace_event/trace_event_impl.cc b/src/base/trace_event/trace_event_impl.cc
index 3fb61b8..48eef34 100644
--- a/src/base/trace_event/trace_event_impl.cc
+++ b/src/base/trace_event/trace_event_impl.cc
@@ -26,7 +26,7 @@
 namespace {
 
 size_t GetAllocLength(const char* str) {
-  return str ? SbStringGetLength(str) + 1 : 0;
+  return str ? strlen(str) + 1 : 0;
 }
 
 // Copies |*member| into |*buffer|, sets |*member| to point to this new
@@ -55,7 +55,7 @@
       phase_(TRACE_EVENT_PHASE_BEGIN) {
   for (int i = 0; i < kTraceMaxNumArgs; ++i)
     arg_names_[i] = nullptr;
-  SbMemorySet(arg_values_, 0, sizeof(arg_values_));
+  memset(arg_values_, 0, sizeof(arg_values_));
 }
 
 TraceEvent::~TraceEvent() = default;
diff --git a/src/base/tuple.h b/src/base/tuple.h
index fc95737..3d7ee4e 100644
--- a/src/base/tuple.h
+++ b/src/base/tuple.h
@@ -29,7 +29,6 @@
 #include <utility>
 
 #include "build/build_config.h"
-#include "nb/cpp14oncpp11.h"
 #include "starboard/types.h"
 
 namespace base {
diff --git a/src/base/values_unittest.cc b/src/base/values_unittest.cc
index bc9701d..784dd02 100644
--- a/src/base/values_unittest.cc
+++ b/src/base/values_unittest.cc
@@ -824,15 +824,15 @@
   ASSERT_EQ(15U, binary->GetBlob().size());
 
   char stack_buffer[42];
-  SbMemorySet(stack_buffer, '!', 42);
+  memset(stack_buffer, '!', 42);
   binary = Value::CreateWithCopiedBuffer(stack_buffer, 42);
   ASSERT_TRUE(binary.get());
   ASSERT_TRUE(binary->GetBlob().data());
   ASSERT_NE(stack_buffer,
             reinterpret_cast<const char*>(binary->GetBlob().data()));
   ASSERT_EQ(42U, binary->GetBlob().size());
-  ASSERT_EQ(0, SbMemoryCompare(stack_buffer, binary->GetBlob().data(),
-                               binary->GetBlob().size()));
+  ASSERT_EQ(0, memcmp(stack_buffer, binary->GetBlob().data(),
+                      binary->GetBlob().size()));
 }
 
 TEST(ValuesTest, StringValue) {
diff --git a/src/build_gyp/common.gypi b/src/build_gyp/common.gypi
index 7665e74..a721f26 100644
--- a/src/build_gyp/common.gypi
+++ b/src/build_gyp/common.gypi
@@ -290,7 +290,6 @@
         # build.
         '-Wno-unused-function',
         '-Wno-char-subscripts',
-        '-Wno-c++11-extensions',
         '-Wno-unnamed-type-template-args',
       ],
 
diff --git a/src/build_overrides/build.gni b/src/build_overrides/build.gni
index 560cb57..c69e1f6 100644
--- a/src/build_overrides/build.gni
+++ b/src/build_overrides/build.gni
@@ -20,3 +20,5 @@
   # Set this flag to true to skip the assertion.
   ignore_elf32_limitations = false
 }
+
+enable_java_templates = false
diff --git a/src/cobalt/CHANGELOG.md b/src/cobalt/CHANGELOG.md
index ce818d5..015db28 100644
--- a/src/cobalt/CHANGELOG.md
+++ b/src/cobalt/CHANGELOG.md
@@ -4,15 +4,24 @@
 
 ## Version 22
  - **C++14 is required to compile Cobalt 22.**
+
    Cobalt code now requires C++14-compatible toolchains to compile. This
    requirement helps us stay updated with C++ standards and integrate
    third-party libraries much easier.
+   C++17 support is recommended, but not yet required to compile Cobalt.
+
+ - **Updated lifecycle handling to support concealed mode.**
+
+   Cobalt now supports a "concealed" state when used with Starboard 13 or later.
+   See (doc/lifecycle.md)[doc/lifecycle.md] for more information.
 
  - **SpiderMonkey(mozjs-45) JavaScript Engine library is removed.**
+
    As stated last year, V8 should be the choice of JavaScript engine on
    every platform. SpiderMonkey is now completely removed.
 
  - **V8 JavaScript Engine is rebased to version v8.8**
+
    We rebased V8 from v7.7 in Cobalt 21 to v8.8 in Cobalt 22. V8 8.8 provides a
    new feature, pointer compression, that reduces JavaScript heap memory usage by
    60% on 64-bit platforms(arm64 and x64), saving about 5MB on startup and more
@@ -20,6 +29,7 @@
    platform uses 64-bit CPU architecture.
 
  - **window.navigator.onLine property and its change events are added.**
+
    To improve user experience during network connect/disconnect situations
    and enable auto-reconnect, Cobalt added web APIs including Navigator.onLine
    property and its change events. To enable using the property and events
@@ -29,15 +39,87 @@
    kSbEventTypeOsNetworkDisconnected Starboard event,
    kSbEventTypeOsNetworkConnected Starboard event.
 
+ - **Added support for User Agent Client Hints.**
+
+   User agent client hints (https://wicg.github.io/ua-client-hints/#interface)
+   is now supported. This does not impact the existing User Agent string.
+
+ - **Added support for Performance Timeline Web API.**
+
+   To facilitate metrics for Cobalt performance, the following web APIs are now
+   supported:
+    - https://www.w3.org/TR/performance-timeline/#the-performanceentry-interface
+    - https://www.w3.org/TR/performance-timeline/#extensions-to-the-performance-interface
+    - https://www.w3.org/TR/performance-timeline/#the-performanceobserver-interface
+    - https://www.w3.org/TR/performance-timeline/#performanceobserverinit-dictionary
+    - https://www.w3.org/TR/performance-timeline/#performanceobserverentrylist-interface
+
+   Additionally, a subset of the following web API is also supported:
+    - https://w3c.github.io/resource-timing/#resources-included-in-the-performanceresourcetiming-interface
+
+ - **Added support for TextEncoder and TextDecoder Web APIs.**
+
+   The following Web APIs are now supported:
+    - https://encoding.spec.whatwg.org/#interface-textencoder
+    - https://encoding.spec.whatwg.org/#interface-textdecoder
+
+ - **Added support for rendering HTML elements with different border styles.**
+
+   Previously, Cobalt only supported borders on elements which used the same
+   border style (e.g. solid) for all sides. This is now fixed.
+
+ - **ICU rebased to version 68.**
+
+   Additionally, ICU data is now packaged as a single file instead of individual
+   files for each locale; this saves about 2MB of storage space compared to the
+   previous version.
+
+ - **Fixed instances where system ICU headers were included.**
+
+   To maintain consistency, only ICU headers from the included version of ICU
+   are used.
+
+ - **Added support for multiple splash screens.**
+
+   See [doc/splash_screen.md](doc/splash_screen.md).
+
+ - **Added Cobalt extension to handle Media Session Web API.**
+
+   This new Cobalt extension allows platform-specific support for Media Session
+   controls.
+
+ - **Deprecated CobaltExtensionConfigurationApi::CobaltJsGarbageCollectionThresholdInBytes.**
+
+   This configuration was only relevant for SpiderMonkey, which has been
+   removed.
+
+ - **Removed Cobalt's custom window.console object.**
+
+   This was only used with SpiderMonkey. V8 has its own handling of the console
+   object so the Cobalt version is no longer needed.
+
+ - **Deprecated depot_tools.**
+
+   Cobalt now uses only built-in git commands for development, and the
+   [setup guide](https://cobalt.dev/development/setup-linux.html) has been changed to reflect that.
+
+ - **Started migration from GYP to GN.**
+
+   The starboard layer can now be built using GN.
+   See `starboard/build/doc/migrating_gyp_to_gn.md`.
+
+
 ## Version 21
 
  - **SpiderMonkey(mozjs-45) JavaScript Engine is no longer supported.**
+
    We will only support V8 from now on. For platforms without Just-In-Time
    compilation ability, please use JIT-less V8 instead. Overriding
    `cobalt_enable_jit` environment variable in `gyp_configuration.py` will
    switch V8 to use JIT-less mode. V8 requires at least Starboard version 10.
 
  - **Runtime V8 snapshot is no longer supported**
+
    V8 has deprecated runtime snapshot and mandated build-time snapshot, Cobalt
    adopts this change as well. Build-time snapshot greatly improves first
    startup speed after install and is required for JIT-less mode.
@@ -146,6 +228,10 @@
    the comment of `SbMediaCanPlayMimeAndKeySystem()` in `media.h` for more
    details.
 
+ - **Added custom web APIs to query memory used by media source extensions.**
+
+   See `cobalt/dom/memory_info.idl` for details.
+
  - **Added support for controlling shutdown behavior of graphics system.**
 
    Cobalt normally clears the framebuffer to opaque black on suspend or exit.
@@ -169,7 +255,6 @@
    Platforms can provide javascript code caching by implementing
    CobaltExtensionJavaScriptCacheApi.
 
-
  - **Added support for UrlFetcher observer.**
 
    Platforms can implement UrlFetcher observer for performance tracing by
@@ -180,6 +265,13 @@
    Platforms can implement CobaltExtensionUpdaterNotificationApi to
    receive notifications from the Cobalt Evergreen Updater.
 
+ - **Improvements and Bugfixes**
+
+   - Fixed rare crash in mouse/pointer event dispatch.
+   - Fixed threading bug with webdriver screenshot handling.
+   - Improved extraction of optional element ID in webdriver moveto handling.
+   - Fixed getClientBoundingRect to factor in scrollLeft / scrollTop.
+
 
 ## Version 20
 
diff --git a/src/cobalt/audio/audio_file_reader_wav.cc b/src/cobalt/audio/audio_file_reader_wav.cc
index 4000dfe..882a496 100644
--- a/src/cobalt/audio/audio_file_reader_wav.cc
+++ b/src/cobalt/audio/audio_file_reader_wav.cc
@@ -200,7 +200,7 @@
   if ((!is_src_sample_in_float && sample_type_ == kSampleTypeInt16) ||
       (is_src_sample_in_float && sample_type_ == kSampleTypeFloat32)) {
     SB_LOG(INFO) << "Copying " << size << " bytes of wav data.";
-    SbMemoryCopy(audio_bus_->interleaved_data(), data + offset, size);
+    memcpy(audio_bus_->interleaved_data(), data + offset, size);
   } else if (!is_src_sample_in_float && sample_type_ == kSampleTypeFloat32) {
     // Convert from int16 to float32
     SB_LOG(INFO) << "Converting " << number_of_frames_ * number_of_channels_
diff --git a/src/cobalt/base/circular_buffer_shell.cc b/src/cobalt/base/circular_buffer_shell.cc
index ece9817..84988bb 100644
--- a/src/cobalt/base/circular_buffer_shell.cc
+++ b/src/cobalt/base/circular_buffer_shell.cc
@@ -101,7 +101,7 @@
     // Copy this segment and do the accounting.
     void* destination = GetWritePointer_Locked();
     const void* src = add_to_pointer(source, produced);
-    SbMemoryCopy(destination, src, to_write);
+    memcpy(destination, src, to_write);
     length_ += to_write;
     produced += to_write;
   }
@@ -150,7 +150,7 @@
     const void* source = add_to_pointer(buffer_, read_position);
     if (destination) {
       void* dest = add_to_pointer(destination, consumed);
-      SbMemoryCopy(dest, source, to_read);
+      memcpy(dest, source, to_read);
     }
     source_length -= to_read;
     read_position = (read_position + to_read) % capacity_;
diff --git a/src/cobalt/base/language.cc b/src/cobalt/base/language.cc
index 819e56a..ed98739 100644
--- a/src/cobalt/base/language.cc
+++ b/src/cobalt/base/language.cc
@@ -62,6 +62,11 @@
   if (U_SUCCESS(icu_result) && buffer[0]) {
     language += "-";
     language += buffer;
+  } else {
+    uloc_addLikelySubtags(NULL, buffer, arraysize(buffer), &icu_result);
+    if (U_SUCCESS(icu_result) && buffer[0]) {
+      return buffer;
+    }
   }
 
   // We should end up with something like "en" or "en-Latn".
diff --git a/src/cobalt/base/token.h b/src/cobalt/base/token.h
index 1ff90c7..1473160 100644
--- a/src/cobalt/base/token.h
+++ b/src/cobalt/base/token.h
@@ -76,11 +76,11 @@
 };
 
 inline bool operator==(const Token& lhs, const std::string& rhs) {
-  return SbStringCompareAll(lhs.c_str(), rhs.c_str()) == 0;
+  return strcmp(lhs.c_str(), rhs.c_str()) == 0;
 }
 
 inline bool operator==(const std::string& lhs, const Token& rhs) {
-  return SbStringCompareAll(lhs.c_str(), rhs.c_str()) == 0;
+  return strcmp(lhs.c_str(), rhs.c_str()) == 0;
 }
 
 inline bool operator!=(const Token& lhs, const Token& rhs) {
@@ -98,7 +98,7 @@
 inline bool operator<(const Token& lhs, const Token& rhs) {
 #ifdef ENABLE_TOKEN_ALPHABETICAL_SORTING
   if (Token::sort_alphabetically()) {
-    return SbStringCompareAll(lhs.c_str(), rhs.c_str()) < 0;
+    return strcmp(lhs.c_str(), rhs.c_str()) < 0;
   }
 #endif  // ENABLE_TOKEN_ALPHABETICAL_SORTING
   return lhs.c_str() < rhs.c_str();
@@ -107,7 +107,7 @@
 inline bool operator>(const Token& lhs, const Token& rhs) {
 #ifdef ENABLE_TOKEN_ALPHABETICAL_SORTING
   if (Token::sort_alphabetically()) {
-    return SbStringCompareAll(lhs.c_str(), rhs.c_str()) > 0;
+    return strcmp(lhs.c_str(), rhs.c_str()) > 0;
   }
 #endif  // ENABLE_TOKEN_ALPHABETICAL_SORTING
   return lhs.c_str() > rhs.c_str();
diff --git a/src/cobalt/base/token_test.cc b/src/cobalt/base/token_test.cc
index 647dc34..4dcb597 100644
--- a/src/cobalt/base/token_test.cc
+++ b/src/cobalt/base/token_test.cc
@@ -71,7 +71,7 @@
   // Sort the vector so we iterate it alphabetically.
   std::sort(tokens.begin(), tokens.end(),
             [](const Token& l, const Token& r) -> bool {
-              return SbStringCompareAll(l.c_str(), r.c_str()) < 0;
+              return strcmp(l.c_str(), r.c_str()) < 0;
             });
 
   // The natural order of the tokens is not alphabetical.
diff --git a/src/cobalt/bindings/README.md b/src/cobalt/bindings/README.md
index 5d3b6a3..18269ee 100644
--- a/src/cobalt/bindings/README.md
+++ b/src/cobalt/bindings/README.md
@@ -45,7 +45,7 @@
 ```
 
 
-In the above example, we first create an `ObjectTemplate`.  This is a structure that can later be fed into V8 that lets it know the "native shape" of the point object.  In particular, the `SetAccessor` lines are the ones that tell it to call into our `GetPointX` function when the property "x" is accessed on a point object.  After V8 calls into the `GetPointX` function, we find the associated native `Point` object, get its x field, convert that value to a JavaScript integer, and then pass that back to JavaScript as the return value.  Note that in SpiderMonkey this process is conceptually identical to V8, however with slightly different APIs.
+In the above example, we first create an `ObjectTemplate`.  This is a structure that can later be fed into V8 that lets it know the "native shape" of the point object.  In particular, the `SetAccessor` lines are the ones that tell it to call into our `GetPointX` function when the property "x" is accessed on a point object.  After V8 calls into the `GetPointX` function, we find the associated native `Point` object, get its x field, convert that value to a JavaScript integer, and then pass that back to JavaScript as the return value.
 
 That pattern, of intercept, convert from JavaScript to native, perform native operations, and then convert the native result back to JavaScript, is the essence of bindings.  Of course, it is far more complicated, in that there are many different types, and more operations that must be performed.  It is important however, to keep this general pattern in mind.
 
@@ -159,7 +159,7 @@
 
 Another important area in this module are utility functions that exist solely for bindings.  In particular, in the [conversion helpers](https://cobalt.googlesource.com/cobalt/+/2a8c847d785c1602f60915c8e0112e0aec6a15a5/src/cobalt/script/v8c/conversion_helpers.h?q=conversion_helpers&sq=package:%5Ecobalt$&dr=CSs) are implemented here, which is a giant file that implements functions to convert back and forth between native Cobalt types and JavaScript values.  These conversion helper functions get called in the native callback implementation for the getters, setters, and functions that we saw at the beginning of this doc (so the stuff that would go inside of GetPointX).  Because these conversion helpers primarily exist for parts of bindings defined by Web IDL, they're on the more complex side (because Web IDL allows for many conversion details to be configurable, such as whether null objects are accepted, or whether integral types should be clamped or not), however they are also used throughout common script/ when it makes sense.
 
-Finally, another critical thing that takes place in script/$engine is what we call [WrapperPrivate](https://cobalt.googlesource.com/cobalt/+/2a8c847d785c1602f60915c8e0112e0aec6a15a5/src/cobalt/script/v8c/wrapper_private.h?type=cs&q=WrapperPrivate&sq=package:%5Ecobalt$&g=0#31) (in both SpiderMonkey and V8).  This is the special type that goes inside of the native only internal object field that was discussed in the beginning of this doc.  WrapperPrivate is a bit more complicated however, as it has to both bridge between Cobalt DOM garbage collection and the JavaScript engine's garbage collection for more details on this), and allow for Cobalt to possibly manipulate garbage collection from the JavaScript side as well (as in add JavaScript objects to the root set of reachable objects).
+Finally, another critical thing that takes place in script/$engine is what we call [WrapperPrivate](https://cobalt.googlesource.com/cobalt/+/2a8c847d785c1602f60915c8e0112e0aec6a15a5/src/cobalt/script/v8c/wrapper_private.h?type=cs&q=WrapperPrivate&sq=package:%5Ecobalt$&g=0#31).  This is the special type that goes inside of the native only internal object field that was discussed in the beginning of this doc.  WrapperPrivate is a bit more complicated however, as it has to both bridge between Cobalt DOM garbage collection and the JavaScript engine's garbage collection for more details on this), and allow for Cobalt to possibly manipulate garbage collection from the JavaScript side as well (as in add JavaScript objects to the root set of reachable objects).
 
 # Testing
 
diff --git a/src/cobalt/bindings/testing/promise_test.cc b/src/cobalt/bindings/testing/promise_test.cc
index c5c7943..c85bc31 100644
--- a/src/cobalt/bindings/testing/promise_test.cc
+++ b/src/cobalt/bindings/testing/promise_test.cc
@@ -38,16 +38,6 @@
 template <typename T>
 using Promise = script::Promise<T>;
 
-// Simple implementation of window.setTimeout. window.setTimeout is needed for
-// the Promise polyfill used in SpiderMonkey 24.
-int32_t SetTimeoutFunction(const Window::TimerCallbackArg& timer_callback,
-                           int32_t timeout) {
-  // Just execute immediately. This is sufficient for the tests below.
-  Handle<Window::TimerCallback> handle(timer_callback);
-  handle->Run();
-  return 1;
-}
-
 class PromiseTest : public InterfaceBindingsTest<PromiseInterface> {
  public:
   ~PromiseTest() {
@@ -57,9 +47,7 @@
   }
 
  protected:
-  void SetUp() {
-    window()->SetSetTimeoutHandler(base::Bind(&SetTimeoutFunction));
-  }
+  void SetUp() {}
 };
 
 }  // namespace
diff --git a/src/cobalt/bindings/testing/window.h b/src/cobalt/bindings/testing/window.h
index 8f29138..9ac16ed 100644
--- a/src/cobalt/bindings/testing/window.h
+++ b/src/cobalt/bindings/testing/window.h
@@ -49,22 +49,6 @@
   void set_on_event(const TestEventHandler&) {}
   const TestEventHandler* on_event() { return NULL; }
 
-  // Stub implementation of window.setTimeout, which is needed for some tests.
-  int SetTimeout(const TimerCallbackArg& handler) {
-    return SetTimeout(handler, 0);
-  }
-
-  int32_t SetTimeout(const TimerCallbackArg& handler, int32_t timeout) {
-    if (!set_timeout_handler_.is_null()) {
-      return set_timeout_handler_.Run(handler, timeout);
-    }
-    return 0;
-  }
-
-  void SetSetTimeoutHandler(const SetTimeoutHandler& handler) {
-    set_timeout_handler_ = handler;
-  }
-
   DEFINE_WRAPPABLE_TYPE(Window);
 
  private:
diff --git a/src/cobalt/bindings/testing/window.idl b/src/cobalt/bindings/testing/window.idl
index dc627f6..3109cf5 100644
--- a/src/cobalt/bindings/testing/window.idl
+++ b/src/cobalt/bindings/testing/window.idl
@@ -21,9 +21,6 @@
 
   // Exercise a similar setup to EventHandler.
   attribute TestEventHandler onEvent;
-
-  // This is needed for the Promise polyfill.
-  long setTimeout(TimerCallback handler, optional long timeout);
 };
 
 // Exercise a similar setup to EventHandler.
diff --git a/src/cobalt/bindings/v8c/generate_conversion_header_v8c.py b/src/cobalt/bindings/v8c/generate_conversion_header_v8c.py
index 4ff30b0..c14dea7 100644
--- a/src/cobalt/bindings/v8c/generate_conversion_header_v8c.py
+++ b/src/cobalt/bindings/v8c/generate_conversion_header_v8c.py
@@ -11,7 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-"""Generate a conversion header for SpiderMonkey."""
+"""Generate a conversion header for V8."""
 
 import sys
 
diff --git a/src/cobalt/black_box_tests/black_box_tests.py b/src/cobalt/black_box_tests/black_box_tests.py
index 43cf1a7..271b2cc 100644
--- a/src/cobalt/black_box_tests/black_box_tests.py
+++ b/src/cobalt/black_box_tests/black_box_tests.py
@@ -34,6 +34,7 @@
 
 _DISABLED_BLACKBOXTEST_CONFIGS = [
     'android-arm/devel',
+    'android-arm64/devel',
     'android-x86/devel',
     'raspi-0/devel',
 ]
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index 91b5874..e186214 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -64,6 +64,7 @@
 #include "cobalt/browser/memory_tracker/tool.h"
 #include "cobalt/browser/storage_upgrade_handler.h"
 #include "cobalt/browser/switches.h"
+#include "cobalt/browser/user_agent_platform_info.h"
 #include "cobalt/browser/user_agent_string.h"
 #include "cobalt/configuration/configuration.h"
 #include "cobalt/extension/crash_handler.h"
@@ -77,6 +78,8 @@
 #include "cobalt/system_window/input_event.h"
 #include "cobalt/trace_event/scoped_trace_to_file.h"
 #include "starboard/configuration.h"
+#include "starboard/event.h"
+#include "starboard/time.h"
 #include "starboard/system.h"
 #include "url/gurl.h"
 
@@ -553,9 +556,9 @@
 #endif
   if (version.empty()) {
     base::StringAppendF(&version, "%s.%s-%s",
-                        platform_info.cobalt_version.c_str(),
-                        platform_info.cobalt_build_version_number.c_str(),
-                        platform_info.build_configuration.c_str());
+                        platform_info.cobalt_version().c_str(),
+                        platform_info.cobalt_build_version_number().c_str(),
+                        platform_info.build_configuration().c_str());
   }
 
   user_agent.push_back('\0');
@@ -563,13 +566,13 @@
   version.push_back('\0');
 
   CrashpadAnnotations crashpad_annotations;
-  SbMemorySet(&crashpad_annotations, sizeof(CrashpadAnnotations), 0);
-  SbStringCopy(crashpad_annotations.user_agent_string, user_agent.c_str(),
-               USER_AGENT_STRING_MAX_SIZE);
-  SbStringCopy(crashpad_annotations.product, product.c_str(),
-               CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
-  SbStringCopy(crashpad_annotations.version, version.c_str(),
-               CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
+  memset(&crashpad_annotations, 0, sizeof(CrashpadAnnotations));
+  strncpy(crashpad_annotations.user_agent_string, user_agent.c_str(),
+          USER_AGENT_STRING_MAX_SIZE);
+  strncpy(crashpad_annotations.product, product.c_str(),
+          CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
+  strncpy(crashpad_annotations.version, version.c_str(),
+          CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
   bool result = static_cast<const CobaltExtensionCrashHandlerApi*>(
                     crash_handler_extension)
                     ->OverrideCrashpadAnnotations(&crashpad_annotations);
@@ -831,7 +834,7 @@
       storage_manager_options));
 
   network_module_.reset(new network::NetworkModule(
-      CreateUserAgentString(GetUserAgentPlatformInfoFromSystem()),
+      CreateUserAgentString(browser::GetUserAgentPlatformInfoFromSystem()),
       storage_manager_.get(), &event_dispatcher_, network_module_options));
 
   AddCrashHandlerAnnotations();
@@ -1010,7 +1013,7 @@
     return;
   }
 
-  OnApplicationEvent(kSbEventTypeStart);
+  OnApplicationEvent(kSbEventTypeStart, SbTimeGetMonotonicNow());
 }
 
 void Application::Quit() {
@@ -1043,7 +1046,8 @@
     case kSbEventTypeFreeze:
     case kSbEventTypeUnfreeze:
     case kSbEventTypeLowMemory:
-      OnApplicationEvent(starboard_event->type);
+      OnApplicationEvent(starboard_event->type,
+                         starboard_event->timestamp);
       break;
 #else
     case kSbEventTypePause:
@@ -1051,7 +1055,7 @@
     case kSbEventTypeSuspend:
     case kSbEventTypeResume:
     case kSbEventTypeLowMemory:
-      OnApplicationEvent(starboard_event->type);
+      OnApplicationEvent(starboard_event->type, SbTimeGetMonotonicNow());
       break;
 #endif  // SB_API_VERSION >= 13
     case kSbEventTypeWindowSizeChanged:
@@ -1147,9 +1151,11 @@
   }
 }
 
-void Application::OnApplicationEvent(SbEventType event_type) {
+void Application::OnApplicationEvent(SbEventType event_type,
+                                     SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "Application::OnApplicationEvent()");
   DCHECK_CALLED_ON_VALID_THREAD(application_event_thread_checker_);
+
   switch (event_type) {
     case kSbEventTypeStop:
       DLOG(INFO) << "Got quit event.";
@@ -1158,35 +1164,35 @@
       break;
     case kSbEventTypeStart:
       DLOG(INFO) << "Got start event.";
-      browser_module_->Reveal();
-      browser_module_->Focus();
+      browser_module_->Reveal(timestamp);
+      browser_module_->Focus(timestamp);
       DLOG(INFO) << "Finished starting.";
       break;
 #if SB_API_VERSION >= 13
     case kSbEventTypeBlur:
       DLOG(INFO) << "Got blur event.";
-      browser_module_->Blur();
+      browser_module_->Blur(timestamp);
       DLOG(INFO) << "Finished blurring.";
       break;
     case kSbEventTypeFocus:
       DLOG(INFO) << "Got focus event.";
-      browser_module_->Focus();
+      browser_module_->Focus(timestamp);
       DLOG(INFO) << "Finished focusing.";
       break;
     case kSbEventTypeConceal:
       DLOG(INFO) << "Got conceal event.";
-      browser_module_->Conceal();
+      browser_module_->Conceal(timestamp);
       DLOG(INFO) << "Finished concealing.";
       break;
     case kSbEventTypeReveal:
       DCHECK(SbSystemSupportsResume());
       DLOG(INFO) << "Got reveal event.";
-      browser_module_->Reveal();
+      browser_module_->Reveal(timestamp);
       DLOG(INFO) << "Finished revealing.";
       break;
     case kSbEventTypeFreeze:
       DLOG(INFO) << "Got freeze event.";
-      browser_module_->Freeze();
+      browser_module_->Freeze(timestamp);
 #if SB_IS(EVERGREEN)
       if (updater_module_) updater_module_->Suspend();
 #endif
@@ -1194,7 +1200,7 @@
       break;
     case kSbEventTypeUnfreeze:
       DLOG(INFO) << "Got unfreeze event.";
-      browser_module_->Unfreeze();
+      browser_module_->Unfreeze(timestamp);
 #if SB_IS(EVERGREEN)
       if (updater_module_) updater_module_->Resume();
 #endif
@@ -1203,18 +1209,18 @@
 #else
     case kSbEventTypePause:
       DLOG(INFO) << "Got pause event.";
-      browser_module_->Blur();
+      browser_module_->Blur(timestamp);
       DLOG(INFO) << "Finished pausing.";
       break;
     case kSbEventTypeUnpause:
       DLOG(INFO) << "Got unpause event.";
-      browser_module_->Focus();
+      browser_module_->Focus(timestamp);
       DLOG(INFO) << "Finished unpausing.";
       break;
     case kSbEventTypeSuspend:
       DLOG(INFO) << "Got suspend event.";
-      browser_module_->Conceal();
-      browser_module_->Freeze();
+      browser_module_->Conceal(timestamp);
+      browser_module_->Freeze(timestamp);
 #if SB_IS(EVERGREEN)
       if (updater_module_) updater_module_->Suspend();
 #endif
@@ -1223,8 +1229,8 @@
     case kSbEventTypeResume:
       DCHECK(SbSystemSupportsResume());
       DLOG(INFO) << "Got resume event.";
-      browser_module_->Unfreeze();
-      browser_module_->Reveal();
+      browser_module_->Unfreeze(timestamp);
+      browser_module_->Reveal(timestamp);
 #if SB_IS(EVERGREEN)
       if (updater_module_) updater_module_->Resume();
 #endif
diff --git a/src/cobalt/browser/application.h b/src/cobalt/browser/application.h
index 94e9edd..620d376 100644
--- a/src/cobalt/browser/application.h
+++ b/src/cobalt/browser/application.h
@@ -67,7 +67,8 @@
   void OnNetworkEvent(const base::Event* event);
 
   // Called to handle an application event.
-  void OnApplicationEvent(SbEventType event_type);
+  void OnApplicationEvent(SbEventType event_type,
+                          SbTimeMonotonic timestamp);
 
   // Called to handle a window size change event.
   void OnWindowSizeChangedEvent(const base::Event* event);
diff --git a/src/cobalt/browser/browser.gyp b/src/cobalt/browser/browser.gyp
index 1422e02..65444e2 100644
--- a/src/cobalt/browser/browser.gyp
+++ b/src/cobalt/browser/browser.gyp
@@ -99,6 +99,8 @@
         'system_platform_error_handler.h',
         'url_handler.cc',
         'url_handler.h',
+        'user_agent_platform_info.cc',
+        'user_agent_platform_info.h',
         'user_agent_string.cc',
         'user_agent_string.h',
         'web_module.cc',
diff --git a/src/cobalt/browser/browser_bindings_gen.gyp b/src/cobalt/browser/browser_bindings_gen.gyp
index 2fdb5b3..9941d47 100644
--- a/src/cobalt/browser/browser_bindings_gen.gyp
+++ b/src/cobalt/browser/browser_bindings_gen.gyp
@@ -59,6 +59,7 @@
         '../dom/captions/system_caption_settings.idl',
         '../dom/cdata_section.idl',
         '../dom/character_data.idl',
+        '../dom/cobalt_ua_data_values_interface.idl',
         '../dom/comment.idl',
         '../dom/crypto.idl',
         '../dom/custom_event.idl',
@@ -133,6 +134,9 @@
         '../dom/on_screen_keyboard.idl',
         '../dom/performance.idl',
         '../dom/performance_entry.idl',
+        '../dom/performance_lifecycle_timing.idl',
+        '../dom/performance_mark.idl',
+        '../dom/performance_measure.idl',
         '../dom/performance_observer.idl',
         '../dom/performance_observer_entry_list.idl',
         '../dom/performance_resource_timing.idl',
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 5c5dc7a..18249fa 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -38,7 +38,6 @@
 #include "cobalt/browser/on_screen_keyboard_starboard_bridge.h"
 #include "cobalt/browser/screen_shot_writer.h"
 #include "cobalt/browser/switches.h"
-#include "cobalt/browser/user_agent_string.h"
 #include "cobalt/browser/webapi_extension.h"
 #include "cobalt/configuration/configuration.h"
 #include "cobalt/cssom/viewport_size.h"
@@ -47,9 +46,13 @@
 #include "cobalt/dom/keyboard_event_init.h"
 #include "cobalt/dom/keycode.h"
 #include "cobalt/dom/mutation_observer_task_manager.h"
+#include "cobalt/dom/navigator.h"
+#include "cobalt/dom/navigator_ua_data.h"
 #include "cobalt/dom/window.h"
+#include "cobalt/extension/graphics.h"
 #include "cobalt/h5vcc/h5vcc.h"
 #include "cobalt/input/input_device_manager_fuzzer.h"
+#include "cobalt/math/matrix3_f.h"
 #include "cobalt/overlay_info/overlay_info_registry.h"
 #include "nb/memory_scope.h"
 #include "starboard/atomic.h"
@@ -194,13 +197,6 @@
 
 #endif  // defined(ENABLE_DEBUGGER)
 
-scoped_refptr<script::Wrappable> CreateH5VCC(
-    const h5vcc::H5vcc::Settings& settings,
-    const scoped_refptr<dom::Window>& window,
-    script::GlobalEnvironment* global_environment) {
-  return scoped_refptr<script::Wrappable>(new h5vcc::H5vcc(settings));
-}
-
 #if SB_API_VERSION < 12
 scoped_refptr<script::Wrappable> CreateExtensionInterface(
     const scoped_refptr<dom::Window>& window,
@@ -245,6 +241,7 @@
       options_(options),
       self_message_loop_(base::MessageLoop::current()),
       event_dispatcher_(event_dispatcher),
+      account_manager_(account_manager),
       is_rendered_(false),
       can_play_type_handler_(media::MediaModule::CreateCanPlayTypeHandler()),
       network_module_(network_module),
@@ -365,16 +362,8 @@
   // Setup our main web module to have the H5VCC API injected into it.
   DCHECK(!ContainsKey(options_.web_module_options.injected_window_attributes,
                       "h5vcc"));
-  h5vcc::H5vcc::Settings h5vcc_settings;
-  h5vcc_settings.media_module = media_module_.get();
-  h5vcc_settings.network_module = network_module_;
-#if SB_IS(EVERGREEN)
-  h5vcc_settings.updater_module = updater_module_;
-#endif
-  h5vcc_settings.account_manager = account_manager;
-  h5vcc_settings.event_dispatcher = event_dispatcher_;
   options_.web_module_options.injected_window_attributes["h5vcc"] =
-      base::Bind(&CreateH5VCC, h5vcc_settings);
+      base::Bind(&BrowserModule::CreateH5vcc, base::Unretained(this));
 
   if (command_line->HasSwitch(switches::kDisableTimerResolutionLimit)) {
     options_.web_module_options.limit_performance_timer_resolution = false;
@@ -471,12 +460,12 @@
   // currently be in, to prepare for shutdown.
   switch (application_state_) {
     case base::kApplicationStateStarted:
-      Blur();
+      Blur(0);
     // Intentional fall-through.
     case base::kApplicationStateBlurred:
-      Conceal();
+      Conceal(0);
     case base::kApplicationStateConcealed:
-      Freeze();
+      Freeze(0);
       break;
     case base::kApplicationStateStopped:
       NOTREACHED() << "BrowserModule does not support the stopped state.";
@@ -1467,53 +1456,55 @@
   network_module_->SetProxy(proxy_rules);
 }
 
-void BrowserModule::Blur() {
+void BrowserModule::Blur(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Blur()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateStarted);
   application_state_ = base::kApplicationStateBlurred;
-  FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Blur());
+  FOR_EACH_OBSERVER(LifecycleObserver,
+                    lifecycle_observers_, Blur(timestamp));
 }
 
-void BrowserModule::Conceal() {
+void BrowserModule::Conceal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Conceal()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateBlurred);
   application_state_ = base::kApplicationStateConcealed;
-  ConcealInternal();
+  ConcealInternal(timestamp);
   OnMaybeFreeze();
 }
 
-void BrowserModule::Focus() {
+void BrowserModule::Focus(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Focus()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateBlurred);
-  FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Focus());
+  FOR_EACH_OBSERVER(LifecycleObserver,
+                    lifecycle_observers_, Focus(timestamp));
   application_state_ = base::kApplicationStateStarted;
 }
 
-void BrowserModule::Freeze() {
+void BrowserModule::Freeze(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Freeze()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateConcealed);
   application_state_ = base::kApplicationStateFrozen;
-  FreezeInternal();
+  FreezeInternal(timestamp);
 }
 
-void BrowserModule::Reveal() {
+void BrowserModule::Reveal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Reveal()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateConcealed);
   application_state_ = base::kApplicationStateBlurred;
-  RevealInternal();
+  RevealInternal(timestamp);
 }
 
-void BrowserModule::Unfreeze() {
+void BrowserModule::Unfreeze(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::Unfreeze()");
   DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
   DCHECK(application_state_ == base::kApplicationStateFrozen);
   application_state_ = base::kApplicationStateConcealed;
-  UnfreezeInternal();
+  UnfreezeInternal(timestamp);
   NavigatePendingURL();
 }
 
@@ -1762,10 +1753,10 @@
   }
 }
 
-void BrowserModule::ConcealInternal() {
+void BrowserModule::ConcealInternal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::ConcealInternal()");
   FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_,
-                    Conceal(GetResourceProvider()));
+                    Conceal(GetResourceProvider(), timestamp));
 
   ResetResources();
 
@@ -1787,15 +1778,16 @@
   }
 }
 
-void BrowserModule::FreezeInternal() {
+void BrowserModule::FreezeInternal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::FreezeInternal()");
   FreezeMediaModule();
   // First freeze all our web modules which implies that they will release
   // their resource provider and all resources created through it.
-  FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Freeze());
+  FOR_EACH_OBSERVER(LifecycleObserver,
+                    lifecycle_observers_, Freeze(timestamp));
 }
 
-void BrowserModule::RevealInternal() {
+void BrowserModule::RevealInternal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::RevealInternal()");
   DCHECK(!renderer_module_);
   if (!system_window_) {
@@ -1812,14 +1804,14 @@
 
   // Set resource provider right after render module initialized.
   FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_,
-                    Reveal(GetResourceProvider()));
+                    Reveal(GetResourceProvider(), timestamp));
 
   if (qr_code_overlay_) {
     qr_code_overlay_->SetResourceProvider(GetResourceProvider());
   }
 }
 
-void BrowserModule::UnfreezeInternal() {
+void BrowserModule::UnfreezeInternal(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::UnfreezeInternal()");
 // Set the Stub resource provider to media module and to web module
 // at Concealed state.
@@ -1828,7 +1820,7 @@
 #endif  // SB_API_VERSION >= 13
 
   FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_,
-                    Unfreeze(GetResourceProvider()));
+                    Unfreeze(GetResourceProvider(), timestamp));
 }
 
 void BrowserModule::OnMaybeFreeze() {
@@ -1860,6 +1852,22 @@
 }
 
 ViewportSize BrowserModule::GetViewportSize() {
+  // If a custom render root transform is used, report the size of the
+  // transformed viewport.
+  math::Matrix3F viewport_transform = math::Matrix3F::Identity();
+  static const CobaltExtensionGraphicsApi* s_graphics_extension =
+      static_cast<const CobaltExtensionGraphicsApi*>(
+          SbSystemGetExtension(kCobaltExtensionGraphicsName));
+  float m00, m01, m02, m10, m11, m12, m20, m21, m22;
+  if (s_graphics_extension &&
+      strcmp(s_graphics_extension->name, kCobaltExtensionGraphicsName) == 0 &&
+      s_graphics_extension->version >= 5 &&
+      s_graphics_extension->GetRenderRootTransform(&m00, &m01, &m02, &m10, &m11,
+                                                   &m12, &m20, &m21, &m22)) {
+    viewport_transform =
+        math::Matrix3F::FromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22);
+  }
+
   // We trust the renderer module for width and height the most, if it exists.
   if (renderer_module_) {
     math::Size target_size = renderer_module_->render_target_size();
@@ -1884,6 +1892,9 @@
           options_.requested_viewport_size->device_pixel_ratio();
     }
 
+    target_size =
+        math::RoundOut(viewport_transform.MapRect(math::RectF(target_size)))
+            .size();
     ViewportSize v(target_size.width(), target_size.height(), diagonal_inches,
                    device_pixel_ratio);
     return v;
@@ -1892,6 +1903,7 @@
   // If the system window exists, that's almost just as good.
   if (system_window_) {
     math::Size size = system_window_->GetWindowSize();
+    size = math::RoundOut(viewport_transform.MapRect(math::RectF(size))).size();
     ViewportSize v(size.width(), size.height(),
                    system_window_->GetDiagonalSizeInches(),
                    system_window_->GetDevicePixelRatio());
@@ -1900,7 +1912,14 @@
 
   // Otherwise, we assume we'll get the viewport size that was requested.
   if (options_.requested_viewport_size) {
-    return *options_.requested_viewport_size;
+    math::Size requested_size =
+        math::RoundOut(viewport_transform.MapRect(math::RectF(
+                           options_.requested_viewport_size->width(),
+                           options_.requested_viewport_size->height())))
+            .size();
+    return ViewportSize(requested_size.width(), requested_size.height(),
+                        options_.requested_viewport_size->diagonal_inches(),
+                        options_.requested_viewport_size->device_pixel_ratio());
   }
 
   // TODO: Allow platforms to define the default window size and return that
@@ -1908,7 +1927,11 @@
 
   // No window and no viewport size was requested, so we return a conservative
   // default.
-  ViewportSize view_size(1280, 720);
+  math::Size default_size(1280, 720);
+  default_size =
+      math::RoundOut(viewport_transform.MapRect(math::RectF(default_size)))
+          .size();
+  ViewportSize view_size(default_size.width(), default_size.height());
   return view_size;
 }
 
@@ -1920,14 +1943,6 @@
 
   LOG(INFO) << auto_mem_->ToPrettyPrintString(SbLogIsTty());
 
-  if (javascript_gc_threshold_in_bytes_) {
-    DCHECK_EQ(*javascript_gc_threshold_in_bytes_,
-              auto_mem_->javascript_gc_threshold_in_bytes()->value());
-  } else {
-    javascript_gc_threshold_in_bytes_ =
-        auto_mem_->javascript_gc_threshold_in_bytes()->value();
-  }
-
   // Web Module options.
   options_.web_module_options.encoded_image_cache_capacity =
       static_cast<int>(auto_mem_->encoded_image_cache_size_in_bytes()->value());
@@ -1935,9 +1950,6 @@
       static_cast<int>(auto_mem_->image_cache_size_in_bytes()->value());
   options_.web_module_options.remote_typeface_cache_capacity = static_cast<int>(
       auto_mem_->remote_typeface_cache_size_in_bytes()->value());
-  options_.web_module_options.javascript_engine_options.gc_threshold_bytes =
-      static_cast<size_t>(
-          auto_mem_->javascript_gc_threshold_in_bytes()->value());
   if (web_module_) {
     web_module_->SetImageCacheCapacity(
         auto_mem_->image_cache_size_in_bytes()->value());
@@ -2007,7 +2019,11 @@
   std::map<std::string, std::string> url_param_map;
   // If this is the initial startup, use topic within deeplink, if specified.
   if (main_web_module_generation_ == 1) {
-    GetParamMap(GetInitialDeepLink(), url_param_map);
+    std::string deeplink = GetInitialDeepLink();
+    size_t query_pos = deeplink.find('?');
+    if (query_pos != std::string::npos) {
+      GetParamMap(deeplink.substr(query_pos + 1), url_param_map);
+    }
   }
   // If this is not the initial startup, there was no deeplink specified, or
   // the deeplink did not have a topic, check the current url for a topic.
@@ -2061,5 +2077,22 @@
   }
 }
 
+scoped_refptr<script::Wrappable> BrowserModule::CreateH5vcc(
+    const scoped_refptr<dom::Window>& window,
+    script::GlobalEnvironment* global_environment) {
+  h5vcc::H5vcc::Settings h5vcc_settings;
+  h5vcc_settings.media_module = media_module_.get();
+  h5vcc_settings.network_module = network_module_;
+#if SB_IS(EVERGREEN)
+  h5vcc_settings.updater_module = updater_module_;
+#endif
+  h5vcc_settings.account_manager = account_manager_;
+  h5vcc_settings.event_dispatcher = event_dispatcher_;
+  h5vcc_settings.user_agent_data = window->navigator()->user_agent_data();
+  h5vcc_settings.global_environment = global_environment;
+
+  return scoped_refptr<script::Wrappable>(new h5vcc::H5vcc(h5vcc_settings));
+}
+
 }  // namespace browser
 }  // namespace cobalt
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h
index 026e593..62bedea 100644
--- a/src/cobalt/browser/browser_module.h
+++ b/src/cobalt/browser/browser_module.h
@@ -66,6 +66,7 @@
 #include "cobalt/system_window/system_window.h"
 #include "cobalt/webdriver/session_driver.h"
 #include "starboard/configuration.h"
+#include "starboard/time.h"
 #include "starboard/window.h"
 #include "url/gurl.h"
 
@@ -175,12 +176,12 @@
   void SetProxy(const std::string& proxy_rules);
 
   // LifecycleObserver-similar interface.
-  void Blur();
-  void Conceal();
-  void Freeze();
-  void Unfreeze();
-  void Reveal();
-  void Focus();
+  void Blur(SbTimeMonotonic timestamp);
+  void Conceal(SbTimeMonotonic timestamp);
+  void Freeze(SbTimeMonotonic timestamp);
+  void Unfreeze(SbTimeMonotonic timestamp);
+  void Reveal(SbTimeMonotonic timestamp);
+  void Focus(SbTimeMonotonic timestamp);
 
   // Attempt to reduce overall memory consumption. Called in response to a
   // system indication that memory usage is nearing a critical level.
@@ -423,23 +424,19 @@
 
   // Does all the steps for half of a Conceal that happen prior to
   // the app state update.
-  void ConcealInternal();
+  void ConcealInternal(SbTimeMonotonic timestamp);
 
   // Does all the steps for half of a Freeze that happen prior to
   // the app state update.
-  void FreezeInternal();
+  void FreezeInternal(SbTimeMonotonic timestamp);
 
   // Does all the steps for half of a Reveal that happen prior to
   // the app state update.
-  void RevealInternal();
-
-  // Does all the steps for half of a Start that happen prior to
-  // the app state update.
-  void StartInternal();
+  void RevealInternal(SbTimeMonotonic timestamp);
 
   // Does all the steps for half of a Unfreeze that happen prior to
   // the app state update.
-  void UnfreezeInternal();
+  void UnfreezeInternal(SbTimeMonotonic timestamp);
 
   // Check debug console, splash screen and web module if they are
   // ready to freeze at Concealed state. If so, call SystemRequestFreeze
@@ -472,6 +469,11 @@
   // Returns the topic used, or an empty Optional if a topic isn't found.
   base::Optional<std::string> SetSplashScreenTopicFallback(const GURL& url);
 
+  // Function that creates the H5vcc object that will be injected into WebModule
+  scoped_refptr<script::Wrappable> CreateH5vcc(
+      const scoped_refptr<dom::Window>& window,
+      script::GlobalEnvironment* global_environment);
+
   // TODO:
   //     WeakPtr usage here can be avoided if BrowserModule has a thread to
   //     own where it can ensure that its tasks are all resolved when it is
@@ -508,6 +510,8 @@
 
   base::EventDispatcher* event_dispatcher_;
 
+  account::AccountManager* account_manager_;
+
   // Whether the browser module has yet rendered anything. On the very first
   // render, we hide the system splash screen.
   bool is_rendered_;
@@ -709,11 +713,6 @@
   int current_splash_screen_timeline_id_;
   int current_main_web_module_timeline_id_;
 
-  // Remember the first set value for JavaScript's GC threshold setting computed
-  // by automem.  We want this so that we can check that it never changes, since
-  // we do not have the ability to modify it after startup.
-  base::Optional<int64_t> javascript_gc_threshold_in_bytes_;
-
   // Save the current window size before transitioning to Concealed state,
   // and reuse this value to recreate the window.
   math::Size window_size_;
diff --git a/src/cobalt/browser/debug_console.h b/src/cobalt/browser/debug_console.h
index 7983443..798154d 100644
--- a/src/cobalt/browser/debug_console.h
+++ b/src/cobalt/browser/debug_console.h
@@ -95,18 +95,27 @@
   }
 
   // LifecycleObserver implementation.
-  void Blur() override { web_module_->Blur(); }
-  void Conceal(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Conceal(resource_provider);
+  void Blur(SbTimeMonotonic timestamp) override {
+    web_module_->Blur(timestamp);
   }
-  void Freeze() override { web_module_->Freeze(); }
-  void Unfreeze(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Unfreeze(resource_provider);
+  void Conceal(render_tree::ResourceProvider* resource_provider,
+               SbTimeMonotonic timestamp) override {
+    web_module_->Conceal(resource_provider, timestamp);
   }
-  void Reveal(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Reveal(resource_provider);
+  void Freeze(SbTimeMonotonic timestamp) override {
+    web_module_->Freeze(timestamp);
   }
-  void Focus() override { web_module_->Focus(); }
+  void Unfreeze(render_tree::ResourceProvider* resource_provider,
+                SbTimeMonotonic timestamp) override {
+    web_module_->Unfreeze(resource_provider, timestamp);
+  }
+  void Reveal(render_tree::ResourceProvider* resource_provider,
+              SbTimeMonotonic timestamp) override {
+    web_module_->Reveal(resource_provider, timestamp);
+  }
+  void Focus(SbTimeMonotonic timestamp) override {
+     web_module_->Focus(timestamp);
+  }
 
   void ReduceMemory() { web_module_->ReduceMemory(); }
 
diff --git a/src/cobalt/browser/lifecycle_observer.h b/src/cobalt/browser/lifecycle_observer.h
index 96241c8..499bb10 100644
--- a/src/cobalt/browser/lifecycle_observer.h
+++ b/src/cobalt/browser/lifecycle_observer.h
@@ -26,29 +26,32 @@
 class LifecycleObserver : public base::CheckedObserver {
  public:
   // Blurs from Started, staying visible and retaining graphics resources.
-  virtual void Blur() = 0;
+  virtual void Blur(SbTimeMonotonic timestamp) = 0;
 
   // Conceals from Blurred, transitioning to invisible but background tasks can
   // still be running.
-  virtual void Conceal(render_tree::ResourceProvider* resource_provider) = 0;
+  virtual void Conceal(render_tree::ResourceProvider* resource_provider,
+                       SbTimeMonotonic timestamp) = 0;
 
   // Freezes from Concealed, and releases its reference to the ResourceProvider,
   // additionally releasing all references to any resources created from
   // it. This method must only be called if the object has previously been
   // Concealed.
-  virtual void Freeze() = 0;
+  virtual void Freeze(SbTimeMonotonic timestamp) = 0;
 
   // Unfreezes from Frozen, with a new ResourceProvider. This method must only
   // be called if the object has previously been Frozen.
-  virtual void Unfreeze(render_tree::ResourceProvider* resource_provider) = 0;
+  virtual void Unfreeze(render_tree::ResourceProvider* resource_provider,
+                        SbTimeMonotonic timestamp) = 0;
 
   // Reveals from Concealed, going back into partially-obscured state. This
   // method must only be called if the object has previously been Concealed.
-  virtual void Reveal(render_tree::ResourceProvider* resource_provider) = 0;
+  virtual void Reveal(render_tree::ResourceProvider* resource_provider,
+                      SbTimeMonotonic timestamp) = 0;
 
   // Focuses, going back to the Started state, and continuing to use the same
   // ResourceProvider and graphics resources.
-  virtual void Focus() = 0;
+  virtual void Focus(SbTimeMonotonic timestamp) = 0;
 
  protected:
   virtual ~LifecycleObserver() {}
diff --git a/src/cobalt/browser/memory_settings/auto_mem.cc b/src/cobalt/browser/memory_settings/auto_mem.cc
index 07d4c08..30a040f 100644
--- a/src/cobalt/browser/memory_settings/auto_mem.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem.cc
@@ -278,7 +278,7 @@
 
   const int64_t target_cpu_memory = GenerateTargetMemoryBytes(
       max_cpu_bytes_->value(), SumAllMemoryOfType(MemorySetting::kCPU),
-      reduced_cpu_bytes_->optional_value());
+      base::Optional<int64_t>(0));
   const int64_t target_gpu_memory = GenerateTargetMemoryBytes(
       max_gpu_bytes_->value(), SumAllMemoryOfType(MemorySetting::kGPU),
       reduced_gpu_bytes_->optional_value());
@@ -310,10 +310,6 @@
   return image_cache_size_in_bytes_.get();
 }
 
-const IntSetting* AutoMem::javascript_gc_threshold_in_bytes() const {
-  return javascript_gc_threshold_in_bytes_.get();
-}
-
 const DimensionSetting* AutoMem::skia_atlas_texture_dimensions() const {
   return skia_atlas_texture_dimensions_.get();
 }
@@ -354,7 +350,6 @@
   // Keep these in alphabetical order.
   all_settings.push_back(encoded_image_cache_size_in_bytes_.get());
   all_settings.push_back(image_cache_size_in_bytes_.get());
-  all_settings.push_back(javascript_gc_threshold_in_bytes_.get());
   all_settings.push_back(misc_cobalt_cpu_size_in_bytes_.get());
   all_settings.push_back(misc_cobalt_gpu_size_in_bytes_.get());
   all_settings.push_back(offscreen_target_cache_size_in_bytes_.get());
@@ -426,20 +421,11 @@
   max_cpu_bytes_ = CreateCpuSetting(command_line_settings, build_settings);
   max_gpu_bytes_ = CreateGpuSetting(command_line_settings, build_settings);
 
-  reduced_cpu_bytes_ = CreateSystemMemorySetting(
-      switches::kReduceCpuMemoryBy, MemorySetting::kCPU,
-      command_line_settings.reduce_cpu_memory_by,
-      build_settings.reduce_cpu_memory_by, -1);
-  if (reduced_cpu_bytes_->value() == -1) {
-    // This effectively disables the value from being used in the constrainer.
-    reduced_cpu_bytes_->set_value(MemorySetting::kUnset, 0);
-  }
-
   reduced_gpu_bytes_ = CreateSystemMemorySetting(
       switches::kReduceGpuMemoryBy, MemorySetting::kGPU,
       command_line_settings.reduce_gpu_memory_by,
       build_settings.reduce_gpu_memory_by, -1);
-  if (reduced_cpu_bytes_->value() == -1) {
+  if (reduced_gpu_bytes_->value() == -1) {
     // This effectively disables the value from being used in the constrainer.
     reduced_gpu_bytes_->set_value(MemorySetting::kUnset, 0);
   }
@@ -468,16 +454,6 @@
   image_cache_size_in_bytes_->set_memory_scaling_function(
       MakeLinearMemoryScaler(.75, 1.0));
 
-  // Set javascript gc threshold
-  JavaScriptGcThresholdSetting* js_setting = new JavaScriptGcThresholdSetting;
-  SetMemorySetting<IntSetting, int64_t>(
-      command_line_settings.javascript_garbage_collection_threshold_in_bytes,
-      build_settings.javascript_garbage_collection_threshold_in_bytes,
-      kDefaultJsGarbageCollectionThresholdSize, js_setting);
-  EnsureValuePositive(js_setting);
-  js_setting->PostInit();
-  javascript_gc_threshold_in_bytes_.reset(js_setting);
-
   // Set the misc cobalt size to a specific size.
   misc_cobalt_cpu_size_in_bytes_.reset(
       new IntSetting("misc_cobalt_cpu_size_in_bytes"));
diff --git a/src/cobalt/browser/memory_settings/auto_mem_settings.cc b/src/cobalt/browser/memory_settings/auto_mem_settings.cc
index a29a0fd..98ef408 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_settings.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_settings.cc
@@ -209,9 +209,6 @@
   settings.cobalt_image_cache_size_in_bytes =
       MakeValidIfGreaterThanOrEqualToZero(
           config->CobaltImageCacheSizeInBytes());
-  settings.javascript_garbage_collection_threshold_in_bytes =
-      MakeValidIfGreaterThanOrEqualToZero(
-          config->CobaltJsGarbageCollectionThresholdInBytes());
   settings.remote_typeface_cache_capacity_in_bytes =
       MakeValidIfGreaterThanOrEqualToZero(
           config->CobaltRemoteTypefaceCacheSizeInBytes());
@@ -241,8 +238,6 @@
 #endif  // defined(COBALT_MAX_GPU_USAGE_IN_BYTES)
 #endif  // SB_API_VERSION < 12
 
-  settings.reduce_cpu_memory_by =
-      MakeValidIfGreaterThanOrEqualToZero(config->CobaltReduceCpuMemoryBy());
   settings.reduce_gpu_memory_by =
       MakeValidIfGreaterThanOrEqualToZero(config->CobaltReduceGpuMemoryBy());
 
@@ -257,8 +252,6 @@
       switches::kEncodedImageCacheSizeInBytes);
   Set(command_line, &settings.cobalt_image_cache_size_in_bytes,
       switches::kImageCacheSizeInBytes);
-  Set(command_line, &settings.javascript_garbage_collection_threshold_in_bytes,
-      switches::kJavaScriptGcThresholdInBytes);
   Set(command_line, &settings.remote_typeface_cache_capacity_in_bytes,
       switches::kRemoteTypefaceCacheSizeInBytes);
   Set(command_line, &settings.skia_cache_size_in_bytes,
@@ -271,8 +264,6 @@
       switches::kOffscreenTargetCacheSizeInBytes);
   Set(command_line, &settings.max_cpu_in_bytes, switches::kMaxCobaltCpuUsage);
   Set(command_line, &settings.max_gpu_in_bytes, switches::kMaxCobaltGpuUsage);
-  Set(command_line, &settings.reduce_cpu_memory_by,
-      switches::kReduceCpuMemoryBy);
   Set(command_line, &settings.reduce_gpu_memory_by,
       switches::kReduceGpuMemoryBy);
 
diff --git a/src/cobalt/browser/memory_settings/auto_mem_settings.h b/src/cobalt/browser/memory_settings/auto_mem_settings.h
index ae3f172..8e1c7bd 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_settings.h
+++ b/src/cobalt/browser/memory_settings/auto_mem_settings.h
@@ -39,7 +39,6 @@
   bool has_blitter;
   base::Optional<int64_t> cobalt_encoded_image_cache_size_in_bytes;
   base::Optional<int64_t> cobalt_image_cache_size_in_bytes;
-  base::Optional<int64_t> javascript_garbage_collection_threshold_in_bytes;
   base::Optional<int64_t> remote_typeface_cache_capacity_in_bytes;
   base::Optional<int64_t> skia_cache_size_in_bytes;
   base::Optional<TextureDimensions> skia_texture_atlas_dimensions;
diff --git a/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc b/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
index 171235a..5f2a555 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
@@ -69,8 +69,6 @@
 
   TEST_PARSE_INT(expected, value, switches::kImageCacheSizeInBytes,
                  cobalt_image_cache_size_in_bytes);
-  TEST_PARSE_INT(expected, value, switches::kJavaScriptGcThresholdInBytes,
-                 javascript_garbage_collection_threshold_in_bytes);
   TEST_PARSE_INT(expected, value, switches::kRemoteTypefaceCacheSizeInBytes,
                  remote_typeface_cache_capacity_in_bytes);
   TEST_PARSE_INT(expected, value, switches::kSkiaCacheSizeInBytes,
@@ -83,8 +81,6 @@
                  max_cpu_in_bytes);
   TEST_PARSE_INT(expected, value, switches::kMaxCobaltGpuUsage,
                  max_gpu_in_bytes);
-  TEST_PARSE_INT(expected, value, switches::kReduceCpuMemoryBy,
-                 reduce_cpu_memory_by);
   TEST_PARSE_INT(expected, value, switches::kReduceGpuMemoryBy,
                  reduce_gpu_memory_by);
 #undef TEST_PARSE_INT
@@ -119,7 +115,6 @@
   AutoMemSettings settings(AutoMemSettings::kTypeCommandLine);
   EXPECT_EQ(AutoMemSettings::kTypeCommandLine, settings.type);
   EXPECT_FALSE(settings.cobalt_image_cache_size_in_bytes);
-  EXPECT_FALSE(settings.javascript_garbage_collection_threshold_in_bytes);
   EXPECT_FALSE(settings.remote_typeface_cache_capacity_in_bytes);
   EXPECT_FALSE(settings.skia_cache_size_in_bytes);
   EXPECT_FALSE(settings.skia_texture_atlas_dimensions);
@@ -127,7 +122,6 @@
   EXPECT_FALSE(settings.offscreen_target_cache_size_in_bytes);
   EXPECT_FALSE(settings.max_cpu_in_bytes);
   EXPECT_FALSE(settings.max_gpu_in_bytes);
-  EXPECT_FALSE(settings.reduce_cpu_memory_by);
   EXPECT_FALSE(settings.reduce_gpu_memory_by);
 
   AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
diff --git a/src/cobalt/browser/memory_settings/auto_mem_test.cc b/src/cobalt/browser/memory_settings/auto_mem_test.cc
index 5a2ee57..0891d87 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_test.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_test.cc
@@ -70,7 +70,6 @@
   // Load up command line settings of command lines.
   AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
   command_line_settings.cobalt_image_cache_size_in_bytes = 1234;
-  command_line_settings.javascript_garbage_collection_threshold_in_bytes = 2345;
   command_line_settings.skia_cache_size_in_bytes = 3456;
   command_line_settings.skia_texture_atlas_dimensions =
       TextureDimensions(1234, 5678, 2);
@@ -83,14 +82,10 @@
 
     AutoMem auto_mem(kResolution1080p, command_line_settings, build_settings);
 
-    // image_cache_size_in_bytes and javascript_gc_threshold_in_bytes settings
-    // ignore the blitter type.
+    // image_cache_size_in_bytes settings ignore the blitter type.
     EXPECT_MEMORY_SETTING(auto_mem.image_cache_size_in_bytes(),
                           MemorySetting::kCmdLine, MemorySetting::kGPU, 1234);
 
-    EXPECT_MEMORY_SETTING(auto_mem.javascript_gc_threshold_in_bytes(),
-                          MemorySetting::kCmdLine, MemorySetting::kCPU, 2345);
-
     if (auto_mem.offscreen_target_cache_size_in_bytes()->valid()) {
       EXPECT_MEMORY_SETTING(auto_mem.offscreen_target_cache_size_in_bytes(),
                             MemorySetting::kCmdLine, MemorySetting::kGPU, 5678);
@@ -263,31 +258,6 @@
 
 // Tests the expectation that constraining the CPU memory to 40MB will result
 // in AutoMem reducing the the memory footprint.
-TEST(AutoMem, ExplicitReducedCPUMemoryConsumption) {
-  // STEP ONE: Get the "natural" size of the engine at the default test
-  // settings.
-  std::unique_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();
-
-  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
-  command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024;
-  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
-                                      build_settings);
-
-  EXPECT_EQ(5 * 1024 * 1024,
-            reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value());
-
-  const int64_t original_memory_consumption =
-      default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
-  const int64_t reduced_memory_consumption =
-      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);
-
-  EXPECT_LE(5 * 1024 * 1024,
-            original_memory_consumption - reduced_memory_consumption);
-}
-
-// Tests the expectation that constraining the CPU memory to 40MB will result
-// in AutoMem reducing the the memory footprint.
 TEST(AutoMem, ExplicitReducedGPUMemoryConsumption) {
   // STEP ONE: Get the "natural" size of the engine at the default test
   // settings.
@@ -296,48 +266,20 @@
   AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
   command_line_settings.reduce_gpu_memory_by = 5 * 1024 * 1024;
   AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
+  AutoMem reduced_gpu_memory_auto_mem(kResolution1080p, command_line_settings,
                                       build_settings);
   EXPECT_EQ(5 * 1024 * 1024,
-            reduced_cpu_memory_auto_mem.reduced_gpu_bytes_->value());
+            reduced_gpu_memory_auto_mem.reduced_gpu_bytes_->value());
 
   const int64_t original_memory_consumption =
       default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU);
   const int64_t reduced_memory_consumption =
-      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kGPU);
+      reduced_gpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kGPU);
 
   EXPECT_LE(5 * 1024 * 1024,
             original_memory_consumption - reduced_memory_consumption);
 }
 
-// Tests the expectation that the max cpu value is ignored when reducing
-// memory.
-TEST(AutoMem, MaxCpuIsIgnoredDuringExplicitMemoryReduction) {
-  // STEP ONE: Get the "natural" size of the engine at the default test
-  // settings.
-  std::unique_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();
-
-  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
-  command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024;
-  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-  build_settings.max_cpu_in_bytes = 1;
-  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
-                                      build_settings);
-
-  EXPECT_EQ(5 * 1024 * 1024,
-            reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value());
-
-  const int64_t original_memory_consumption =
-      default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
-  const int64_t reduced_memory_consumption =
-      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);
-
-  // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
-  // this for this test to pass.
-  EXPECT_LE(5 * 1024 * 1024,
-            original_memory_consumption - reduced_memory_consumption);
-}
-
 // Tests the expectation that the constrainer will not run on cpu memory if
 // --reduce_cpu_memory_by is set to 0.
 TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceCPUCommand) {
diff --git a/src/cobalt/browser/memory_settings/memory_settings.cc b/src/cobalt/browser/memory_settings/memory_settings.cc
index 7b51884..b854265 100644
--- a/src/cobalt/browser/memory_settings/memory_settings.cc
+++ b/src/cobalt/browser/memory_settings/memory_settings.cc
@@ -131,19 +131,6 @@
   return num_of_reductions;
 }
 
-JavaScriptGcThresholdSetting::JavaScriptGcThresholdSetting()
-    : IntSetting(switches::kJavaScriptGcThresholdInBytes) {}
-
-void JavaScriptGcThresholdSetting::PostInit() {
-  const int64_t normal_memory_consumption = MemoryConsumption();
-  const int64_t min_memory_consumption =
-      std::min<int64_t>(normal_memory_consumption, 1 * 1024 * 1024);
-
-  ScalingFunction function =
-      MakeJavaScriptGCScaler(min_memory_consumption, normal_memory_consumption);
-  set_memory_scaling_function(function);
-}
-
 int64_t SumMemoryConsumption(
     base::Optional<MemorySetting::MemoryType> memory_type_filter,
     const std::vector<const MemorySetting*>& memory_settings) {
diff --git a/src/cobalt/browser/memory_settings/memory_settings.h b/src/cobalt/browser/memory_settings/memory_settings.h
index afaeef6..6b3a0b1 100644
--- a/src/cobalt/browser/memory_settings/memory_settings.h
+++ b/src/cobalt/browser/memory_settings/memory_settings.h
@@ -181,12 +181,6 @@
   static size_t NumberOfReductions(double reduction_factor);
 };
 
-class JavaScriptGcThresholdSetting : public IntSetting {
- public:
-  JavaScriptGcThresholdSetting();
-  void PostInit();
-};
-
 int64_t SumMemoryConsumption(
     base::Optional<MemorySetting::MemoryType> memory_type_filter,
     const std::vector<const MemorySetting*>& memory_settings);
diff --git a/src/cobalt/browser/memory_settings/pretty_print_test.cc b/src/cobalt/browser/memory_settings/pretty_print_test.cc
index 9f4ffe5..98c1323 100644
--- a/src/cobalt/browser/memory_settings/pretty_print_test.cc
+++ b/src/cobalt/browser/memory_settings/pretty_print_test.cc
@@ -50,7 +50,7 @@
       SB_DLOG(INFO) << "Token \"" << token << "\" not found in order.";
       return false;
     }
-    current_position = position + SbStringGetLength(token);
+    current_position = position + strlen(token);
   }
   return true;
 }
@@ -67,7 +67,6 @@
       actual_string,
       {"SETTING NAME", "VALUE", "TYPE", "SOURCE", "\n",
        "image_cache_size_in_bytes", "1234", "0.0 MB", "GPU", "CmdLine", "\n",
-       "javascript_gc_threshold_in_bytes", "1112", "0.0 MB", "CPU", "AutoSet", "\n",  // NOLINT(whitespace/line_length)
        "skia_atlas_texture_dimensions", "1234x4567x2", "10.7 MB", "GPU", "CmdLine", "\n",  // NOLINT(whitespace/line_length)
        "skia_cache_size_in_bytes", "12345678", "11.8 MB", "GPU", "CmdLine", "\n",  // NOLINT(whitespace/line_length)
        "software_surface_cache_size_in_bytes", "N/A", "N/A", "N/A", "N/A", "\n"
diff --git a/src/cobalt/browser/memory_settings/scaling_function.cc b/src/cobalt/browser/memory_settings/scaling_function.cc
index a9d879f..e88eb66 100644
--- a/src/cobalt/browser/memory_settings/scaling_function.cc
+++ b/src/cobalt/browser/memory_settings/scaling_function.cc
@@ -29,33 +29,6 @@
 namespace memory_settings {
 namespace {
 
-class JavaScriptGCMemoryScaler {
- public:
-  JavaScriptGCMemoryScaler(int64_t min_memory, int64_t max_memory) {
-    DCHECK_LE(min_memory, max_memory);
-    min_memory = std::min(min_memory, max_memory);
-    const double min_factor =
-        static_cast<double>(min_memory) / static_cast<double>(max_memory);
-    // From 95% -> 0%, the memory will stay the same. This effectively
-    // clamps the minimum value.
-    interp_table_.Add(0.0, min_factor);
-
-    // At 95% memory, the memory falls to the min_factor. The rationale here
-    // is that most of the memory for JavaScript can be eliminated without
-    // a large performance penalty, so it's quickly reduced.
-    interp_table_.Add(.95, min_factor);
-
-    // At 100% we have 100% of memory.
-    interp_table_.Add(1.0, 1.0);
-  }
-  double Factor(double requested_memory_scale) const {
-    return interp_table_.Map(requested_memory_scale);
-  }
-
- private:
-  math::LinearInterpolator<double, double> interp_table_;
-};
-
 double LinearFunctionWithClampValue(double min_clamp_value,
                                     double max_clamp_value,
                                     double requested_memory_scale) {
@@ -79,15 +52,6 @@
   return function;
 }
 
-ScalingFunction MakeJavaScriptGCScaler(int64_t min_consumption,
-                                       int64_t max_consumption) {
-  JavaScriptGCMemoryScaler* constrainer =
-      new JavaScriptGCMemoryScaler(min_consumption, max_consumption);
-  // Note that Bind() will implicitly ref-count the constrainer pointer.
-  return base::Bind(&JavaScriptGCMemoryScaler::Factor,
-                    base::Owned(constrainer));
-}
-
 ScalingFunction MakeSkiaGlyphAtlasMemoryScaler() {
   ScalingFunction function = base::Bind(&SkiaAtlasGlyphTextureConstrainer);
   return function;
diff --git a/src/cobalt/browser/memory_settings/scaling_function.h b/src/cobalt/browser/memory_settings/scaling_function.h
index 4206037..33a4498 100644
--- a/src/cobalt/browser/memory_settings/scaling_function.h
+++ b/src/cobalt/browser/memory_settings/scaling_function.h
@@ -160,11 +160,6 @@
 ScalingFunction MakeLinearMemoryScaler(double min_clamp_value,
                                        double max_clamp_value);
 
-// Generates a functor that will shed most of the memory of the JavaScriptGC
-// very quickly.
-ScalingFunction MakeJavaScriptGCScaler(int64_t min_consumption,
-                                       int64_t max_consumption);
-
 // Generates a functor that will shed 50% of memory when the requested
 // memory scale is .5 or less, otherwise no memory is reduced.
 ScalingFunction MakeSkiaGlyphAtlasMemoryScaler();
diff --git a/src/cobalt/browser/memory_settings/table_printer_test.cc b/src/cobalt/browser/memory_settings/table_printer_test.cc
index d29c9a7..8c01b4d 100644
--- a/src/cobalt/browser/memory_settings/table_printer_test.cc
+++ b/src/cobalt/browser/memory_settings/table_printer_test.cc
@@ -49,7 +49,7 @@
       SB_DLOG(INFO) << "Token \"" << token << "\" not found in order.";
       return false;
     }
-    current_position = position + SbStringGetLength(token);
+    current_position = position + strlen(token);
   }
   return true;
 }
diff --git a/src/cobalt/browser/memory_settings/test_common.h b/src/cobalt/browser/memory_settings/test_common.h
index 6aa7b75..56cfafe 100644
--- a/src/cobalt/browser/memory_settings/test_common.h
+++ b/src/cobalt/browser/memory_settings/test_common.h
@@ -72,9 +72,6 @@
     MakeSetting(MemorySetting::kCmdLine, MemorySetting::kGPU,
                 switches::kImageCacheSizeInBytes, 1234);
 
-    MakeSetting(MemorySetting::kAutoSet, MemorySetting::kCPU,
-                switches::kJavaScriptGcThresholdInBytes, 1112);
-
     MakeSetting(MemorySetting::kCmdLine, MemorySetting::kGPU,
                 switches::kSkiaTextureAtlasDimensions,
                 TextureDimensions(1234, 4567, 2));
diff --git a/src/cobalt/browser/memory_tracker/tool/buffered_file_writer.cc b/src/cobalt/browser/memory_tracker/tool/buffered_file_writer.cc
index 9993d56..73d3b47 100644
--- a/src/cobalt/browser/memory_tracker/tool/buffered_file_writer.cc
+++ b/src/cobalt/browser/memory_tracker/tool/buffered_file_writer.cc
@@ -36,7 +36,7 @@
       diskwrite_cond_(diskwrite_mutex_),
       quit_thread_(false),
       file_path_(file_path) {
-  SbMemorySet(log_buffers_, 0, sizeof(log_buffers_));
+  memset(log_buffers_, 0, sizeof(log_buffers_));
   StartThread();
 }
 
@@ -95,7 +95,7 @@
   }
 
   LogBuffer& current_buffer = log_buffers_[current_log_buffer_];
-  SbMemoryCopy(current_buffer.buffer + current_buffer.num_bytes, data,
+  memcpy(current_buffer.buffer + current_buffer.num_bytes, data,
                num_bytes);
   current_buffer.num_bytes += num_bytes;
   return;
diff --git a/src/cobalt/browser/memory_tracker/tool/leak_finder_tool.cc b/src/cobalt/browser/memory_tracker/tool/leak_finder_tool.cc
index d5a158a..31a89a3 100644
--- a/src/cobalt/browser/memory_tracker/tool/leak_finder_tool.cc
+++ b/src/cobalt/browser/memory_tracker/tool/leak_finder_tool.cc
@@ -55,7 +55,7 @@
        it != callstack.end(); ++it) {
     const NbMemoryScopeInfo* memory_scope = *it;
     const bool is_javascript_scope =
-        SbStringFindString(memory_scope->memory_scope_name_, "Javascript");
+        strstr(memory_scope->memory_scope_name_, "Javascript");
     if (is_javascript_scope) {
       return true;
     }
@@ -259,9 +259,9 @@
     const NbMemoryScopeInfo* memory_scope = callstack.back();
 
     const bool skip =
-        SbStringFindString(memory_scope->function_name_, "js_malloc") ||
-        SbStringFindString(memory_scope->function_name_, "js_realloc") ||
-        SbStringFindString(memory_scope->function_name_, "new_");
+        strstr(memory_scope->function_name_, "js_malloc") ||
+        strstr(memory_scope->function_name_, "js_realloc") ||
+        strstr(memory_scope->function_name_, "new_");
 
     // Skip up one callstack because we don't want to track calls to
     // allocation functions.
diff --git a/src/cobalt/browser/memory_tracker/tool/log_writer_tool.cc b/src/cobalt/browser/memory_tracker/tool/log_writer_tool.cc
index c41b1a1..b8dd168 100644
--- a/src/cobalt/browser/memory_tracker/tool/log_writer_tool.cc
+++ b/src/cobalt/browser/memory_tracker/tool/log_writer_tool.cc
@@ -91,7 +91,7 @@
     buff_pos += static_cast<size_t>(bytes_written);
   }
   // Adds a "\n" at the end.
-  SbStringConcat(buff + buff_pos, "\n", static_cast<int>(n - buff_pos));
+  starboard::strlcat(buff + buff_pos, "\n", static_cast<int>(n - buff_pos));
   buffered_file_writer_->Append(buff, strlen(buff));
 }
 
diff --git a/src/cobalt/browser/memory_tracker/tool/malloc_logger_tool.cc b/src/cobalt/browser/memory_tracker/tool/malloc_logger_tool.cc
index 9455c7f..ddaca24 100644
--- a/src/cobalt/browser/memory_tracker/tool/malloc_logger_tool.cc
+++ b/src/cobalt/browser/memory_tracker/tool/malloc_logger_tool.cc
@@ -141,8 +141,8 @@
   }
 
   // Adds a "\n" at the end.
-  bytes_written = SbStringConcat(buff + buff_pos, "\"\n",
-                                 static_cast<int>(kRecordLimit - buff_pos));
+  bytes_written = starboard::strlcat(buff + buff_pos, "\"\n",
+                                     static_cast<int>(kRecordLimit - buff_pos));
   buff_pos += bytes_written;
   buffered_file_writer_->Append(buff, buff_pos);
 }
diff --git a/src/cobalt/browser/memory_tracker/tool/util.cc b/src/cobalt/browser/memory_tracker/tool/util.cc
index fd57c06..e865670 100644
--- a/src/cobalt/browser/memory_tracker/tool/util.cc
+++ b/src/cobalt/browser/memory_tracker/tool/util.cc
@@ -39,7 +39,7 @@
   if (pos == kNotFound) {
     return haystack;
   }
-  const size_t n = SbStringGetLength(needle);
+  const size_t n = strlen(needle);
   std::string output;
   output.reserve(haystack.size());
 
@@ -196,8 +196,8 @@
 
 const char* BaseNameFast(const char* file_name) {
   // Case: Linux.
-  const char* end_pos = file_name + SbStringGetLength(file_name);
-  const char* last_forward_slash = SbStringFindLastCharacter(file_name, '/');
+  const char* end_pos = file_name + strlen(file_name);
+  const char* last_forward_slash = strrchr(file_name, '/');
   if (last_forward_slash) {
     if (end_pos != last_forward_slash) {
       ++last_forward_slash;
@@ -206,7 +206,7 @@
   }
 
   // Case: Windows.
-  const char* last_backward_slash = SbStringFindLastCharacter(file_name, '\\');
+  const char* last_backward_slash = strrchr(file_name, '\\');
   if (last_backward_slash) {
     if (end_pos != last_backward_slash) {
       ++last_backward_slash;
diff --git a/src/cobalt/browser/splash_screen.h b/src/cobalt/browser/splash_screen.h
index 381280f..3f0595d 100644
--- a/src/cobalt/browser/splash_screen.h
+++ b/src/cobalt/browser/splash_screen.h
@@ -53,18 +53,27 @@
   }
 
   // LifecycleObserver implementation.
-  void Blur() override { web_module_->Blur(); }
-  void Conceal(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Conceal(resource_provider);
+  void Blur(SbTimeMonotonic timestamp) override {
+    web_module_->Blur(timestamp);
   }
-  void Freeze() override { web_module_->Freeze(); }
-  void Unfreeze(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Unfreeze(resource_provider);
+  void Conceal(render_tree::ResourceProvider* resource_provider,
+               SbTimeMonotonic timestamp) override {
+    web_module_->Conceal(resource_provider, timestamp);
   }
-  void Reveal(render_tree::ResourceProvider* resource_provider) override {
-    web_module_->Reveal(resource_provider);
+  void Freeze(SbTimeMonotonic timestamp) override {
+    web_module_->Freeze(timestamp);
   }
-  void Focus() override { web_module_->Focus(); }
+  void Unfreeze(render_tree::ResourceProvider* resource_provider,
+                SbTimeMonotonic timestamp) override {
+    web_module_->Unfreeze(resource_provider, timestamp);
+  }
+  void Reveal(render_tree::ResourceProvider* resource_provider,
+              SbTimeMonotonic timestamp) override {
+    web_module_->Reveal(resource_provider, timestamp);
+  }
+  void Focus(SbTimeMonotonic timestamp) override {
+    web_module_->Focus(timestamp);
+  }
 
   void ReduceMemory() { web_module_->ReduceMemory(); }
 
diff --git a/src/cobalt/browser/splash_screen_cache.cc b/src/cobalt/browser/splash_screen_cache.cc
index 58b9caf..a139f6f 100644
--- a/src/cobalt/browser/splash_screen_cache.cc
+++ b/src/cobalt/browser/splash_screen_cache.cc
@@ -40,11 +40,11 @@
   }
   std::size_t prev_found = 0;
   std::size_t found = key.find(kSbFileSepString);
-  SbStringConcat(path.data(), kSbFileSepString, kSbFileMaxPath);
+  starboard::strlcat(path.data(), kSbFileSepString, kSbFileMaxPath);
   while (found != std::string::npos) {
-    SbStringConcat(path.data(),
-                   key.substr(prev_found, found - prev_found).c_str(),
-                   kSbFileMaxPath);
+    starboard::strlcat(path.data(),
+                       key.substr(prev_found, found - prev_found).c_str(),
+                       kSbFileMaxPath);
     if (!SbDirectoryCreate(path.data())) {
       return false;
     }
@@ -175,7 +175,7 @@
                                          std::vector<char>& path,
                                          std::string& subpath) const {
   std::string subcomponent = kSbFileSepString + directory;
-  if (SbStringConcat(path.data(), subcomponent.c_str(), kSbFileMaxPath) >=
+  if (starboard::strlcat(path.data(), subcomponent.c_str(), kSbFileMaxPath) >=
       static_cast<int>(kSbFileMaxPath)) {
     return false;
   }
diff --git a/src/cobalt/browser/switches.cc b/src/cobalt/browser/switches.cc
index 249e0b3..1411c37 100644
--- a/src/cobalt/browser/switches.cc
+++ b/src/cobalt/browser/switches.cc
@@ -273,11 +273,6 @@
     "Setting this switch defines the startup URL that Cobalt will use.  If no "
     "value is set, a default URL will be used.";
 
-const char kJavaScriptGcThresholdInBytes[] = "javascript_gc_threshold_in_bytes";
-const char kJavaScriptGcThresholdInBytesHelp[] =
-    "Specifies the javascript gc threshold. When this amount of garbage has "
-    "collected then the garbage collector will begin running.";
-
 const char kLocalStoragePartitionUrl[] = "local_storage_partition_url";
 const char kLocalStoragePartitionUrlHelp[] =
     "Overrides the default storage partition with a custom partition URL to "
@@ -324,11 +319,6 @@
     " and the number of locations can be overwritten by specifying it as the "
     " value of the command line parameter, like '--qr_code_overlay=6'.";
 
-const char kReduceCpuMemoryBy[] = "reduce_cpu_memory_by";
-const char kReduceCpuMemoryByHelp[] =
-    "Reduces the cpu-memory of the system by this amount. This causes AutoMem "
-    "to reduce the runtime size of the CPU-Memory caches.";
-
 const char kReduceGpuMemoryBy[] = "reduce_gpu_memory_by";
 const char kReduceGpuMemoryByHelp[] =
     "Reduces the gpu-memory of the system by this amount. This causes AutoMem "
@@ -470,7 +460,6 @@
         {kHelp, kHelpHelp},
         {kImageCacheSizeInBytes, kImageCacheSizeInBytesHelp},
         {kInitialURL, kInitialURLHelp},
-        {kJavaScriptGcThresholdInBytes, kJavaScriptGcThresholdInBytesHelp},
         {kLocalStoragePartitionUrl, kLocalStoragePartitionUrlHelp},
         {kMaxCobaltCpuUsage, kMaxCobaltCpuUsageHelp},
         {kMaxCobaltGpuUsage, kMaxCobaltGpuUsageHelp},
@@ -480,7 +469,6 @@
         {kOmitDeviceAuthenticationQueryParameters,
          kOmitDeviceAuthenticationQueryParametersHelp},
         {kProxy, kProxyHelp}, {kQrCodeOverlay, kQrCodeOverlayHelp},
-        {kReduceCpuMemoryBy, kReduceCpuMemoryByHelp},
         {kReduceGpuMemoryBy, kReduceGpuMemoryByHelp},
         {kRemoteTypefaceCacheSizeInBytes, kRemoteTypefaceCacheSizeInBytesHelp},
         {kRetainRemoteTypefaceCacheDuringSuspend,
diff --git a/src/cobalt/browser/switches.h b/src/cobalt/browser/switches.h
index 94f052b..53fe622 100644
--- a/src/cobalt/browser/switches.h
+++ b/src/cobalt/browser/switches.h
@@ -115,8 +115,6 @@
 extern const char kImageCacheSizeInBytesHelp[];
 extern const char kInitialURL[];
 extern const char kInitialURLHelp[];
-extern const char kJavaScriptGcThresholdInBytes[];
-extern const char kJavaScriptGcThresholdInBytesHelp[];
 extern const char kLocalStoragePartitionUrl[];
 extern const char kLocalStoragePartitionUrlHelp[];
 extern const char kMaxCobaltCpuUsage[];
@@ -133,8 +131,6 @@
 extern const char kProxyHelp[];
 extern const char kQrCodeOverlay[];
 extern const char kQrCodeOverlayHelp[];
-extern const char kReduceCpuMemoryBy[];
-extern const char kReduceCpuMemoryByHelp[];
 extern const char kReduceGpuMemoryBy[];
 extern const char kReduceGpuMemoryByHelp[];
 extern const char kRemoteTypefaceCacheSizeInBytes[];
diff --git a/src/cobalt/browser/user_agent_platform_info.cc b/src/cobalt/browser/user_agent_platform_info.cc
new file mode 100644
index 0000000..50a703f
--- /dev/null
+++ b/src/cobalt/browser/user_agent_platform_info.cc
@@ -0,0 +1,205 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cobalt/browser/user_agent_platform_info.h"
+
+#include <memory>
+
+#include "base/command_line.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "cobalt/browser/switches.h"
+#include "cobalt/renderer/get_default_rasterizer_for_platform.h"
+#include "cobalt/script/javascript_engine.h"
+#include "cobalt/version.h"
+#include "cobalt_build_id.h"  // NOLINT(build/include)
+#include "starboard/common/log.h"
+#include "starboard/common/string.h"
+#include "starboard/system.h"
+#if SB_IS(EVERGREEN)
+#include "cobalt/updater/utils.h"
+#endif
+
+namespace cobalt {
+namespace browser {
+
+namespace {
+
+std::string CreateDeviceTypeString(SbSystemDeviceType device_type) {
+  switch (device_type) {
+    case kSbSystemDeviceTypeBlueRayDiskPlayer:
+      return "BDP";
+    case kSbSystemDeviceTypeGameConsole:
+      return "GAME";
+    case kSbSystemDeviceTypeOverTheTopBox:
+      return "OTT";
+    case kSbSystemDeviceTypeSetTopBox:
+      return "STB";
+    case kSbSystemDeviceTypeTV:
+      return "TV";
+    case kSbSystemDeviceTypeAndroidTV:
+      return "ATV";
+    case kSbSystemDeviceTypeDesktopPC:
+      return "DESKTOP";
+    case kSbSystemDeviceTypeUnknown:
+      return "UNKNOWN";
+    default:
+      NOTREACHED();
+      return "";
+  }
+}
+
+std::string CreateConnectionTypeString(
+    const base::Optional<SbSystemConnectionType>& connection_type) {
+  if (connection_type) {
+    switch (*connection_type) {
+      case kSbSystemConnectionTypeWired:
+        return "Wired";
+      case kSbSystemConnectionTypeWireless:
+        return "Wireless";
+      default:
+        NOTREACHED();
+    }
+  }
+
+  return "";
+}
+
+}  // namespace
+
+UserAgentPlatformInfo::UserAgentPlatformInfo() { InitializeFields(); }
+
+void UserAgentPlatformInfo::set_device_type(SbSystemDeviceType device_type) {
+  device_type_ = device_type;
+  device_type_string_ = CreateDeviceTypeString(device_type_);
+}
+
+void UserAgentPlatformInfo::set_connection_type(
+    base::Optional<SbSystemConnectionType> connection_type) {
+  if (connection_type) {
+    connection_type_ = connection_type;
+    connection_type_string_ = CreateConnectionTypeString(connection_type_);
+  } else {
+    connection_type_string_ = "";
+  }
+}
+
+void UserAgentPlatformInfo::InitializeFields() {
+  starboard_version_ = base::StringPrintf("Starboard/%d", SB_API_VERSION);
+
+  const size_t kSystemPropertyMaxLength = 1024;
+  char value[kSystemPropertyMaxLength];
+  bool result;
+
+  result = SbSystemGetProperty(kSbSystemPropertyPlatformName, value,
+                               kSystemPropertyMaxLength);
+  SB_DCHECK(result);
+  os_name_and_version_ = value;
+
+  // Fill platform info if it is a hardware TV device.
+  SbSystemDeviceType device_type = SbSystemGetDeviceType();
+
+#if SB_API_VERSION >= 12
+  // System Integrator
+  result = SbSystemGetProperty(kSbSystemPropertySystemIntegratorName, value,
+                               kSystemPropertyMaxLength);
+#else
+  // Original Design Manufacturer (ODM)
+  result = SbSystemGetProperty(kSbSystemPropertyOriginalDesignManufacturerName,
+                               value, kSystemPropertyMaxLength);
+#endif
+  if (result) {
+    original_design_manufacturer_ = value;
+  }
+
+  javascript_engine_version_ = script::GetJavaScriptEngineNameAndVersion();
+
+  rasterizer_type_ =
+      renderer::GetDefaultRasterizerForPlatform().rasterizer_name;
+
+// Evergreen version
+#if SB_IS(EVERGREEN)
+  evergreen_version_ = updater::GetCurrentEvergreenVersion();
+#endif
+
+  cobalt_version_ = COBALT_VERSION;
+  cobalt_build_version_number_ = COBALT_BUILD_VERSION_NUMBER;
+
+#if defined(COBALT_BUILD_TYPE_DEBUG)
+  build_configuration_ = "debug";
+#elif defined(COBALT_BUILD_TYPE_DEVEL)
+  build_configuration_ = "devel";
+#elif defined(COBALT_BUILD_TYPE_QA)
+  build_configuration_ = "qa";
+#elif defined(COBALT_BUILD_TYPE_GOLD)
+  build_configuration_ = "gold";
+#else
+#error Unknown build configuration.
+#endif
+
+  result = SbSystemGetProperty(kSbSystemPropertyUserAgentAuxField, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    aux_field_ = value;
+  }
+
+  // Device Type
+  device_type_ = device_type;
+  device_type_string_ = CreateDeviceTypeString(device_type_);
+
+  // Chipset model number
+  result = SbSystemGetProperty(kSbSystemPropertyChipsetModelNumber, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    chipset_model_number_ = value;
+  }
+
+  // Model year
+  result = SbSystemGetProperty(kSbSystemPropertyModelYear, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    model_year_ = value;
+  }
+
+  // Firmware version
+  result = SbSystemGetProperty(kSbSystemPropertyFirmwareVersion, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    firmware_version_ = value;
+  }
+
+  // Brand
+  result = SbSystemGetProperty(kSbSystemPropertyBrandName, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    brand_ = value;
+  }
+
+  // Model name
+  result = SbSystemGetProperty(kSbSystemPropertyModelName, value,
+                               kSystemPropertyMaxLength);
+  if (result) {
+    model_ = value;
+  }
+
+  // Connection type
+  SbSystemConnectionType connection_type = SbSystemGetConnectionType();
+  if (connection_type != kSbSystemConnectionTypeUnknown) {
+    connection_type_ = connection_type;
+  }
+  connection_type_string_ = CreateConnectionTypeString(connection_type_);
+}
+
+}  // namespace browser
+}  // namespace cobalt
diff --git a/src/cobalt/browser/user_agent_platform_info.h b/src/cobalt/browser/user_agent_platform_info.h
new file mode 100644
index 0000000..80d9798
--- /dev/null
+++ b/src/cobalt/browser/user_agent_platform_info.h
@@ -0,0 +1,177 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_BROWSER_USER_AGENT_PLATFORM_INFO_H_
+#define COBALT_BROWSER_USER_AGENT_PLATFORM_INFO_H_
+
+#include <string>
+
+#include "cobalt/dom/user_agent_platform_info.h"
+
+namespace cobalt {
+namespace browser {
+
+class UserAgentPlatformInfo : public dom::UserAgentPlatformInfo {
+ public:
+  UserAgentPlatformInfo();
+  ~UserAgentPlatformInfo() override{};
+
+  // From: dom:UserAgentPlatformInfo
+  //
+  const std::string& starboard_version() const override {
+    return starboard_version_;
+  }
+  const std::string& os_name_and_version() const override {
+    return os_name_and_version_;
+  }
+  base::Optional<std::string> original_design_manufacturer() const override {
+    return original_design_manufacturer_;
+  }
+  SbSystemDeviceType device_type() const override { return device_type_; }
+  const std::string& device_type_string() const override {
+    return device_type_string_;
+  }
+  base::Optional<std::string> chipset_model_number() const override {
+    return chipset_model_number_;
+  }
+  base::Optional<std::string> model_year() const override {
+    return model_year_;
+  }
+  base::Optional<std::string> firmware_version() const override {
+    return firmware_version_;
+  }
+  base::Optional<std::string> brand() const override { return brand_; }
+  base::Optional<std::string> model() const override { return model_; }
+  const std::string& aux_field() const override { return aux_field_; }
+  base::Optional<SbSystemConnectionType> connection_type() const override {
+    return connection_type_;
+  }
+  const std::string& connection_type_string() const override {
+    return connection_type_string_;
+  }
+  const std::string& javascript_engine_version() const override {
+    return javascript_engine_version_;
+  }
+  const std::string& rasterizer_type() const override {
+    return rasterizer_type_;
+  }
+  const std::string& evergreen_version() const override {
+    return evergreen_version_;
+  }
+  const std::string& cobalt_version() const override { return cobalt_version_; }
+  const std::string& cobalt_build_version_number() const override {
+    return cobalt_build_version_number_;
+  }
+  const std::string& build_configuration() const override {
+    return build_configuration_;
+  }
+
+  // Other: For unit testing cobalt::browser::CreateUserAgentString()
+  //
+  void set_starboard_version(const std::string& starboard_version) {
+    starboard_version_ = starboard_version;
+  }
+  void set_os_name_and_version(const std::string& os_name_and_version) {
+    os_name_and_version_ = os_name_and_version;
+  }
+  void set_original_design_manufacturer(
+      base::Optional<std::string> original_design_manufacturer) {
+    if (original_design_manufacturer) {
+      original_design_manufacturer_ = original_design_manufacturer;
+    }
+  }
+  void set_device_type(SbSystemDeviceType device_type);
+  void set_chipset_model_number(
+      base::Optional<std::string> chipset_model_number) {
+    if (chipset_model_number) {
+      chipset_model_number_ = chipset_model_number;
+    }
+  }
+  void set_model_year(base::Optional<std::string> model_year) {
+    if (model_year) {
+      model_year_ = model_year;
+    }
+  }
+  void set_firmware_version(base::Optional<std::string> firmware_version) {
+    if (firmware_version) {
+      firmware_version_ = firmware_version;
+    }
+  }
+  void set_brand(base::Optional<std::string> brand) {
+    if (brand) {
+      brand_ = brand;
+    }
+  }
+  void set_model(base::Optional<std::string> model) {
+    if (model) {
+      model_ = model;
+    }
+  }
+  void set_aux_field(const std::string& aux_field) { aux_field_ = aux_field; }
+  void set_connection_type(
+      base::Optional<SbSystemConnectionType> connection_type);
+  void set_javascript_engine_version(
+      const std::string& javascript_engine_version) {
+    javascript_engine_version_ = javascript_engine_version;
+  }
+  void set_rasterizer_type(const std::string& rasterizer_type) {
+    rasterizer_type_ = rasterizer_type;
+  }
+  void set_evergreen_version(const std::string& evergreen_version) {
+    evergreen_version_ = evergreen_version;
+  }
+  void set_cobalt_version(const std::string& cobalt_version) {
+    cobalt_version_ = cobalt_version;
+  }
+  void set_cobalt_build_version_number(
+      const std::string& cobalt_build_version_number) {
+    cobalt_build_version_number_ = cobalt_build_version_number;
+  }
+  void set_build_configuration(const std::string& build_configuration) {
+    build_configuration_ = build_configuration;
+  }
+
+ private:
+  // Function that will query Starboard and populate a UserAgentPlatformInfo
+  // object based on those results.  This is de-coupled from
+  // CreateUserAgentString() so that the common logic in CreateUserAgentString()
+  // can be easily unit tested.
+  void InitializeFields();
+
+  std::string starboard_version_;
+  std::string os_name_and_version_;
+  base::Optional<std::string> original_design_manufacturer_;
+  SbSystemDeviceType device_type_ = kSbSystemDeviceTypeUnknown;
+  std::string device_type_string_;
+  base::Optional<std::string> chipset_model_number_;
+  base::Optional<std::string> model_year_;
+  base::Optional<std::string> firmware_version_;
+  base::Optional<std::string> brand_;
+  base::Optional<std::string> model_;
+  std::string aux_field_;
+  base::Optional<SbSystemConnectionType> connection_type_;
+  std::string connection_type_string_;
+  std::string javascript_engine_version_;
+  std::string rasterizer_type_;
+  std::string evergreen_version_;
+
+  std::string cobalt_version_;
+  std::string cobalt_build_version_number_;
+  std::string build_configuration_;
+};
+
+}  // namespace browser
+}  // namespace cobalt
+
+#endif  // COBALT_BROWSER_USER_AGENT_PLATFORM_INFO_H_
diff --git a/src/cobalt/browser/user_agent_string.cc b/src/cobalt/browser/user_agent_string.cc
index c016789..fde8edb 100644
--- a/src/cobalt/browser/user_agent_string.cc
+++ b/src/cobalt/browser/user_agent_string.cc
@@ -20,16 +20,12 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "cobalt/browser/switches.h"
-#include "cobalt/renderer/get_default_rasterizer_for_platform.h"
-#include "cobalt/script/javascript_engine.h"
-#include "cobalt/version.h"
-#include "cobalt_build_id.h"  // NOLINT(build/include)
+#if SB_IS(EVERGREEN)
+#include "cobalt/extension/installation_manager.h"
+#endif  // SB_IS(EVERGREEN)
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/system.h"
-#if SB_IS(EVERGREEN)
-#include "cobalt/updater/utils.h"
-#endif
 
 namespace cobalt {
 namespace browser {
@@ -58,150 +54,10 @@
   return clean;
 }
 
-std::string CreateDeviceTypeString(SbSystemDeviceType device_type) {
-  switch (device_type) {
-    case kSbSystemDeviceTypeBlueRayDiskPlayer:
-      return "BDP";
-    case kSbSystemDeviceTypeGameConsole:
-      return "GAME";
-    case kSbSystemDeviceTypeOverTheTopBox:
-      return "OTT";
-    case kSbSystemDeviceTypeSetTopBox:
-      return "STB";
-    case kSbSystemDeviceTypeTV:
-      return "TV";
-    case kSbSystemDeviceTypeAndroidTV:
-      return "ATV";
-    case kSbSystemDeviceTypeDesktopPC:
-      return "DESKTOP";
-    case kSbSystemDeviceTypeUnknown:
-      return "UNKNOWN";
-    default:
-      NOTREACHED();
-      return "";
-  }
-}
-
-std::string CreateConnectionTypeString(
-    const base::Optional<SbSystemConnectionType>& connection_type) {
-  if (connection_type) {
-    switch (*connection_type) {
-      case kSbSystemConnectionTypeWired:
-        return "Wired";
-      case kSbSystemConnectionTypeWireless:
-        return "Wireless";
-      default:
-        NOTREACHED();
-    }
-  }
-
-  return "";
-}
-
 }  // namespace
 
 UserAgentPlatformInfo GetUserAgentPlatformInfoFromSystem() {
   UserAgentPlatformInfo platform_info;
-
-  platform_info.starboard_version =
-      base::StringPrintf("Starboard/%d", SB_API_VERSION);
-
-  const size_t kSystemPropertyMaxLength = 1024;
-  char value[kSystemPropertyMaxLength];
-  bool result;
-
-  result = SbSystemGetProperty(kSbSystemPropertyPlatformName, value,
-                               kSystemPropertyMaxLength);
-  SB_DCHECK(result);
-  platform_info.os_name_and_version = value;
-
-  // Fill platform info if it is a hardware TV device.
-  SbSystemDeviceType device_type = SbSystemGetDeviceType();
-
-#if SB_API_VERSION >= 12
-  // System Integrator
-  result = SbSystemGetProperty(kSbSystemPropertySystemIntegratorName, value,
-                               kSystemPropertyMaxLength);
-#else
-  // Original Design Manufacturer (ODM)
-  result = SbSystemGetProperty(kSbSystemPropertyOriginalDesignManufacturerName,
-                               value, kSystemPropertyMaxLength);
-#endif
-  if (result) {
-    platform_info.original_design_manufacturer = value;
-  }
-
-  platform_info.javascript_engine_version =
-      script::GetJavaScriptEngineNameAndVersion();
-
-  platform_info.rasterizer_type =
-      renderer::GetDefaultRasterizerForPlatform().rasterizer_name;
-
-  platform_info.cobalt_version = COBALT_VERSION;
-  platform_info.cobalt_build_version_number = COBALT_BUILD_VERSION_NUMBER;
-
-#if defined(COBALT_BUILD_TYPE_DEBUG)
-  platform_info.build_configuration = "debug";
-#elif defined(COBALT_BUILD_TYPE_DEVEL)
-  platform_info.build_configuration = "devel";
-#elif defined(COBALT_BUILD_TYPE_QA)
-  platform_info.build_configuration = "qa";
-#elif defined(COBALT_BUILD_TYPE_GOLD)
-  platform_info.build_configuration = "gold";
-#else
-#error Unknown build configuration.
-#endif
-
-  result = SbSystemGetProperty(kSbSystemPropertyUserAgentAuxField, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.aux_field = value;
-  }
-
-  // Device Type
-  platform_info.device_type = device_type;
-
-  // Chipset model number
-  result = SbSystemGetProperty(kSbSystemPropertyChipsetModelNumber, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.chipset_model_number = value;
-  }
-
-  // Model year
-  result = SbSystemGetProperty(kSbSystemPropertyModelYear, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.model_year = value;
-  }
-
-  // Firmware version
-  result = SbSystemGetProperty(kSbSystemPropertyFirmwareVersion, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.firmware_version = value;
-  }
-
-  // Brand
-  result = SbSystemGetProperty(kSbSystemPropertyBrandName, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.brand = value;
-  }
-
-  // Model name
-  result = SbSystemGetProperty(kSbSystemPropertyModelName, value,
-                               kSystemPropertyMaxLength);
-  if (result) {
-    platform_info.model = value;
-  }
-
-  // Connection type
-  SbSystemConnectionType connection_type = SbSystemGetConnectionType();
-  if (connection_type != kSbSystemConnectionTypeUnknown) {
-    platform_info.connection_type = connection_type;
-  }
-
   return platform_info;
 }
 
@@ -216,7 +72,7 @@
   //   Starboard/APIVersion,
   //   Device/FirmwareVersion (Brand, Model, ConnectionType)
 
-  std::string os_name_and_version = platform_info.os_name_and_version;
+  std::string os_name_and_version = platform_info.os_name_and_version();
 
 #if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
   // Because we add Cobalt's user agent string to Crashpad before we actually
@@ -237,52 +93,59 @@
 
   //   Cobalt/Version.BuildNumber-BuildConfiguration (unlike Gecko)
   base::StringAppendF(&user_agent, " Cobalt/%s.%s-%s (unlike Gecko)",
-                      platform_info.cobalt_version.c_str(),
-                      platform_info.cobalt_build_version_number.c_str(),
-                      platform_info.build_configuration.c_str());
+                      platform_info.cobalt_version().c_str(),
+                      platform_info.cobalt_build_version_number().c_str(),
+                      platform_info.build_configuration().c_str());
 
   // JavaScript Engine Name/Version
-  if (!platform_info.javascript_engine_version.empty()) {
+  if (!platform_info.javascript_engine_version().empty()) {
     base::StringAppendF(&user_agent, " %s",
-                        platform_info.javascript_engine_version.c_str());
+                        platform_info.javascript_engine_version().c_str());
   }
 
   // Rasterizer Type
-  if (!platform_info.rasterizer_type.empty()) {
+  if (!platform_info.rasterizer_type().empty()) {
     base::StringAppendF(&user_agent, " %s",
-                        platform_info.rasterizer_type.c_str());
+                        platform_info.rasterizer_type().c_str());
   }
 
-// Evergreen version
-#if SB_IS(EVERGREEN)
-  const std::string evergreen_version = updater::GetCurrentEvergreenVersion();
-  if (!evergreen_version.empty()) {
+  // Evergreen version
+  if (!platform_info.evergreen_version().empty()) {
     base::StringAppendF(&user_agent, " Evergreen/%s",
-                        evergreen_version.c_str());
+                        platform_info.evergreen_version().c_str());
+#if SB_IS(EVERGREEN)
+    if (!SbSystemGetExtension(kCobaltExtensionInstallationManagerName)) {
+      // If the installation manager is not initialized, the "evergreen_lite"
+      // command line parameter is specified and the system image is loaded.
+      base::StringAppendF(&user_agent, " Evergreen-Lite");
+    } else {
+      base::StringAppendF(&user_agent, " Evergreen-Full");
+    }
+#endif  // SB_IS(EVERGREEN)
   }
-#endif
 
   // Starboard/APIVersion,
-  if (!platform_info.starboard_version.empty()) {
+  if (!platform_info.starboard_version().empty()) {
     base::StringAppendF(&user_agent, " %s",
-                        platform_info.starboard_version.c_str());
+                        platform_info.starboard_version().c_str());
   }
 
   // Device/FirmwareVersion (Brand, Model, ConnectionType)
   base::StringAppendF(
       &user_agent, ", %s_%s_%s_%s/%s (%s, %s, %s)",
-      Sanitize(platform_info.original_design_manufacturer.value_or("")).c_str(),
-      CreateDeviceTypeString(platform_info.device_type).c_str(),
-      Sanitize(platform_info.chipset_model_number.value_or("")).c_str(),
-      Sanitize(platform_info.model_year.value_or("")).c_str(),
-      Sanitize(platform_info.firmware_version.value_or("")).c_str(),
-      Sanitize(platform_info.brand.value_or("")).c_str(),
-      Sanitize(platform_info.model.value_or("")).c_str(),
-      CreateConnectionTypeString(platform_info.connection_type).c_str());
+      Sanitize(platform_info.original_design_manufacturer().value_or(""))
+          .c_str(),
+      platform_info.device_type_string().c_str(),
+      Sanitize(platform_info.chipset_model_number().value_or("")).c_str(),
+      Sanitize(platform_info.model_year().value_or("")).c_str(),
+      Sanitize(platform_info.firmware_version().value_or("")).c_str(),
+      Sanitize(platform_info.brand().value_or("")).c_str(),
+      Sanitize(platform_info.model().value_or("")).c_str(),
+      platform_info.connection_type_string().c_str());
 
-  if (!platform_info.aux_field.empty()) {
+  if (!platform_info.aux_field().empty()) {
     user_agent.append(" ");
-    user_agent.append(platform_info.aux_field);
+    user_agent.append(platform_info.aux_field());
   }
   return user_agent;
 }
diff --git a/src/cobalt/browser/user_agent_string.h b/src/cobalt/browser/user_agent_string.h
index 432ccdf..a3326b9 100644
--- a/src/cobalt/browser/user_agent_string.h
+++ b/src/cobalt/browser/user_agent_string.h
@@ -18,32 +18,11 @@
 #include <string>
 
 #include "base/optional.h"
+#include "cobalt/browser/user_agent_platform_info.h"
 
 namespace cobalt {
 namespace browser {
 
-struct UserAgentPlatformInfo {
-  UserAgentPlatformInfo() : device_type(kSbSystemDeviceTypeUnknown) {}
-
-  std::string starboard_version;
-  std::string os_name_and_version;
-  base::Optional<std::string> original_design_manufacturer;
-  SbSystemDeviceType device_type;
-  base::Optional<std::string> chipset_model_number;
-  base::Optional<std::string> model_year;
-  base::Optional<std::string> firmware_version;
-  base::Optional<std::string> brand;
-  base::Optional<std::string> model;
-  std::string aux_field;
-  base::Optional<SbSystemConnectionType> connection_type;
-  std::string javascript_engine_version;
-  std::string rasterizer_type;
-
-  std::string cobalt_version;
-  std::string cobalt_build_version_number;
-  std::string build_configuration;
-};
-
 // Function that will query Starboard and populate a UserAgentPlatformInfo
 // structure based on those results.  This is de-coupled from
 // CreateUserAgentString() so that the common logic in CreateUserAgentString()
diff --git a/src/cobalt/browser/user_agent_string_test.cc b/src/cobalt/browser/user_agent_string_test.cc
index 194513b..042d180 100644
--- a/src/cobalt/browser/user_agent_string_test.cc
+++ b/src/cobalt/browser/user_agent_string_test.cc
@@ -21,9 +21,31 @@
 
 namespace {
 
-UserAgentPlatformInfo CreateOnlyOSNameAndVersionPlatformInfo() {
+UserAgentPlatformInfo CreateEmptyPlatformInfo() {
   UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
+  platform_info.set_starboard_version("");
+  platform_info.set_os_name_and_version("");
+  platform_info.set_original_design_manufacturer("");
+  platform_info.set_device_type(kSbSystemDeviceTypeUnknown);
+  platform_info.set_chipset_model_number("");
+  platform_info.set_model_year("");
+  platform_info.set_firmware_version("");
+  platform_info.set_brand("");
+  platform_info.set_model("");
+  platform_info.set_aux_field("");
+  platform_info.set_connection_type(base::nullopt);
+  platform_info.set_javascript_engine_version("");
+  platform_info.set_rasterizer_type("");
+  platform_info.set_evergreen_version("");
+  platform_info.set_cobalt_version("");
+  platform_info.set_cobalt_build_version_number("");
+  platform_info.set_build_configuration("");
+  return platform_info;
+}
+
+UserAgentPlatformInfo CreateOnlyOSNameAndVersionPlatformInfo() {
+  UserAgentPlatformInfo platform_info = CreateEmptyPlatformInfo();
+  platform_info.set_os_name_and_version("GLaDOS 3.11");
   return platform_info;
 }
 
@@ -46,11 +68,11 @@
 }
 
 TEST(UserAgentStringFactoryTest, WithCobaltVersionAndConfiguration) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
-  platform_info.cobalt_version = "16";
-  platform_info.cobalt_build_version_number = "123456";
-  platform_info.build_configuration = "gold";
+  UserAgentPlatformInfo platform_info =
+      CreateOnlyOSNameAndVersionPlatformInfo();
+  platform_info.set_cobalt_version("16");
+  platform_info.set_cobalt_build_version_number("123456");
+  platform_info.set_build_configuration("gold");
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   const char* tv_info_str = "Cobalt/16.123456-gold (unlike Gecko)";
@@ -67,15 +89,15 @@
 TEST(UserAgentStringFactoryTest, WithPlatformInfo) {
   // There are deliberately a variety of underscores, commas, slashes, and
   // parentheses in the strings below to ensure they get sanitized.
-  UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
-  platform_info.original_design_manufacturer = "Aperture_Science_Innovators";
-  platform_info.device_type = kSbSystemDeviceTypeOverTheTopBox;
-  platform_info.chipset_model_number = "P-body/Orange_Atlas/Blue";
-  platform_info.model_year = "2013";
-  platform_info.firmware_version = "0,01";
-  platform_info.brand = "Aperture Science (Labs)";
-  platform_info.model = "GLaDOS";
+  UserAgentPlatformInfo platform_info =
+      CreateOnlyOSNameAndVersionPlatformInfo();
+  platform_info.set_original_design_manufacturer("Aperture_Science_Innovators");
+  platform_info.set_device_type(kSbSystemDeviceTypeOverTheTopBox);
+  platform_info.set_chipset_model_number("P-body/Orange_Atlas/Blue");
+  platform_info.set_model_year("2013");
+  platform_info.set_firmware_version("0,01");
+  platform_info.set_brand("Aperture Science (Labs)");
+  platform_info.set_model("GLaDOS");
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   const char* tv_info_str =
@@ -90,31 +112,31 @@
 }
 
 TEST(UserAgentStringFactoryTest, WithWiredConnection) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
-  platform_info.connection_type = kSbSystemConnectionTypeWired;
-  platform_info.device_type = kSbSystemDeviceTypeOverTheTopBox;
+  UserAgentPlatformInfo platform_info =
+      CreateOnlyOSNameAndVersionPlatformInfo();
+  platform_info.set_connection_type(kSbSystemConnectionTypeWired);
+  platform_info.set_device_type(kSbSystemDeviceTypeOverTheTopBox);
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   EXPECT_NE(std::string::npos, user_agent_string.find("Wired"));
 }
 
 TEST(UserAgentStringFactoryTest, WithWirelessConnection) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
-  platform_info.connection_type = kSbSystemConnectionTypeWireless;
-  platform_info.device_type = kSbSystemDeviceTypeOverTheTopBox;
+  UserAgentPlatformInfo platform_info =
+      CreateOnlyOSNameAndVersionPlatformInfo();
+  platform_info.set_connection_type(kSbSystemConnectionTypeWireless);
+  platform_info.set_device_type(kSbSystemDeviceTypeOverTheTopBox);
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   EXPECT_NE(std::string::npos, user_agent_string.find("Wireless"));
 }
 
 TEST(UserAgentStringFactoryTest, WithOnlyBrandModelAndDeviceType) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.os_name_and_version = "GLaDOS 3.11";
-  platform_info.device_type = kSbSystemDeviceTypeOverTheTopBox;
-  platform_info.brand = "Aperture Science";
-  platform_info.model = "GLaDOS";
+  UserAgentPlatformInfo platform_info =
+      CreateOnlyOSNameAndVersionPlatformInfo();
+  platform_info.set_device_type(kSbSystemDeviceTypeOverTheTopBox);
+  platform_info.set_brand("Aperture Science");
+  platform_info.set_model("GLaDOS");
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   const char* tv_info_str = ", _OTT__/ (Aperture Science, GLaDOS, )";
@@ -122,9 +144,9 @@
 }
 
 TEST(UserAgentStringFactoryTest, WithStarboardVersion) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.starboard_version = "Starboard/6";
-  platform_info.device_type = kSbSystemDeviceTypeOverTheTopBox;
+  UserAgentPlatformInfo platform_info = CreateEmptyPlatformInfo();
+  platform_info.set_starboard_version("Starboard/6");
+  platform_info.set_device_type(kSbSystemDeviceTypeOverTheTopBox);
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   const char* tv_info_str = "Starboard/6, _OTT__/ (, , )";
@@ -132,8 +154,8 @@
 }
 
 TEST(UserAgentStringFactoryTest, WithJavaScriptVersion) {
-  UserAgentPlatformInfo platform_info;
-  platform_info.javascript_engine_version = "V8/6.5.254.28";
+  UserAgentPlatformInfo platform_info = CreateEmptyPlatformInfo();
+  platform_info.set_javascript_engine_version("V8/6.5.254.28");
   std::string user_agent_string = CreateUserAgentString(platform_info);
 
   EXPECT_NE(std::string::npos, user_agent_string.find("V8/6.5.254.28"));
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index 1468005..764516e 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -228,12 +228,15 @@
 
   // See LifecycleObserver. These functions do not implement the interface, but
   // have the same basic function.
-  void Blur();
-  void Conceal(render_tree::ResourceProvider* resource_provider);
-  void Freeze();
-  void Unfreeze(render_tree::ResourceProvider* resource_provider);
-  void Reveal(render_tree::ResourceProvider* resource_provider);
-  void Focus();
+  void Blur(SbTimeMonotonic timestamp);
+  void Conceal(render_tree::ResourceProvider* resource_provider,
+               SbTimeMonotonic timestamp);
+  void Freeze(SbTimeMonotonic timestamp);
+  void Unfreeze(render_tree::ResourceProvider* resource_provider,
+                SbTimeMonotonic timestamp);
+  void Reveal(render_tree::ResourceProvider* resource_provider,
+              SbTimeMonotonic timestamp);
+  void Focus(SbTimeMonotonic timestamp);
 
   void ReduceMemory();
   void GetJavaScriptHeapStatistics(
@@ -379,6 +382,8 @@
   // tracker are contained within it.
   std::unique_ptr<browser::WebModuleStatTracker> web_module_stat_tracker_;
 
+  std::unique_ptr<browser::UserAgentPlatformInfo> platform_info_;
+
   // Post and run tasks to notify MutationObservers.
   dom::MutationObserverTaskManager mutation_observer_task_manager_;
 
@@ -577,6 +582,9 @@
       new browser::WebModuleStatTracker(name_, data.options.track_event_stats));
   DCHECK(web_module_stat_tracker_);
 
+  platform_info_.reset(new browser::UserAgentPlatformInfo());
+  DCHECK(platform_info_);
+
   javascript_engine_ = script::JavaScriptEngine::CreateEngine(
       data.options.javascript_engine_options);
   DCHECK(javascript_engine_);
@@ -649,6 +657,8 @@
       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseTTS);
 #endif
 
+  std::unique_ptr<UserAgentPlatformInfo> platform_info(
+      new UserAgentPlatformInfo());
   window_ = new dom::Window(
       environment_settings_.get(), data.window_dimensions,
       data.initial_application_state, css_parser_.get(), dom_parser_.get(),
@@ -660,12 +670,9 @@
       script_runner_.get(), global_environment_->script_value_factory(),
       media_source_registry_.get(),
       web_module_stat_tracker_->dom_stat_tracker(), data.initial_url,
-      data.network_module->GetUserAgent(),
+      data.network_module->GetUserAgent(), platform_info_.get(),
       data.network_module->preferred_language(),
-      data.options.font_language_script_override.empty()
-          ? base::GetSystemLanguageScript()
-          : data.options.font_language_script_override,
-      data.options.navigation_callback,
+      base::GetSystemLanguageScript(), data.options.navigation_callback,
       base::Bind(&WebModule::Impl::OnLoadComplete, base::Unretained(this)),
       data.network_module->cookie_jar(), data.network_module->GetPostSender(),
       data.options.require_csp, data.options.csp_enforcement_mode,
@@ -798,6 +805,7 @@
   global_environment_ = NULL;
   javascript_engine_.reset();
   web_module_stat_tracker_.reset();
+  platform_info_.reset();
   local_storage_database_.reset();
   mesh_cache_.reset();
   remote_typeface_cache_.reset();
@@ -1140,13 +1148,14 @@
       layout_manager_->IsRenderTreePending());
 }
 
-void WebModule::Impl::Blur() {
+void WebModule::Impl::Blur(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Blur()");
   SetApplicationState(base::kApplicationStateBlurred);
 }
 
 void WebModule::Impl::Conceal(
-    render_tree::ResourceProvider* resource_provider) {
+    render_tree::ResourceProvider* resource_provider,
+    SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Conceal()");
   SetResourceProvider(resource_provider);
 
@@ -1177,7 +1186,7 @@
   SetApplicationState(base::kApplicationStateConcealed);
 }
 
-void WebModule::Impl::Freeze() {
+void WebModule::Impl::Freeze(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Freeze()");
 
   // Clear out the loader factory's resource provider, possibly aborting any
@@ -1187,7 +1196,8 @@
 }
 
 void WebModule::Impl::Unfreeze(
-    render_tree::ResourceProvider* resource_provider) {
+    render_tree::ResourceProvider* resource_provider,
+    SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Unfreeze()");
   synchronous_loader_interrupt_.Reset();
   DCHECK(resource_provider);
@@ -1196,7 +1206,9 @@
   SetApplicationState(base::kApplicationStateConcealed);
 }
 
-void WebModule::Impl::Reveal(render_tree::ResourceProvider* resource_provider) {
+void WebModule::Impl::Reveal(
+  render_tree::ResourceProvider* resource_provider,
+  SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Reveal()");
   synchronous_loader_interrupt_.Reset();
   DCHECK(resource_provider);
@@ -1211,7 +1223,7 @@
   SetApplicationState(base::kApplicationStateBlurred);
 }
 
-void WebModule::Impl::Focus() {
+void WebModule::Impl::Focus(SbTimeMonotonic timestamp) {
   TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Focus()");
   synchronous_loader_interrupt_.Reset();
   SetApplicationState(base::kApplicationStateStarted);
@@ -1657,14 +1669,15 @@
                             base::Unretained(impl_.get()), bytes));
 }
 
-void WebModule::Blur() {
+void WebModule::Blur(SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
   impl_->CancelSynchronousLoads();
 
   auto impl_blur =
-      base::Bind(&WebModule::Impl::Blur, base::Unretained(impl_.get()));
+      base::Bind(&WebModule::Impl::Blur,
+                 base::Unretained(impl_.get()), timestamp);
 
 #if defined(ENABLE_DEBUGGER)
   // We normally need to block here so that the call doesn't return until the
@@ -1684,7 +1697,8 @@
   message_loop()->task_runner()->PostBlockingTask(FROM_HERE, impl_blur);
 }
 
-void WebModule::Conceal(render_tree::ResourceProvider* resource_provider) {
+void WebModule::Conceal(render_tree::ResourceProvider* resource_provider,
+                        SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
@@ -1694,10 +1708,11 @@
   // application has had a chance to process the whole event.
   message_loop()->task_runner()->PostBlockingTask(
       FROM_HERE, base::Bind(&WebModule::Impl::Conceal,
-                            base::Unretained(impl_.get()), resource_provider));
+                            base::Unretained(impl_.get()),
+                            resource_provider, timestamp));
 }
 
-void WebModule::Freeze() {
+void WebModule::Freeze(SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
@@ -1705,34 +1720,40 @@
   // application has had a chance to process the whole event.
   message_loop()->task_runner()->PostBlockingTask(
       FROM_HERE,
-      base::Bind(&WebModule::Impl::Freeze, base::Unretained(impl_.get())));
+      base::Bind(&WebModule::Impl::Freeze,
+                 base::Unretained(impl_.get()), timestamp));
 }
 
-void WebModule::Unfreeze(render_tree::ResourceProvider* resource_provider) {
+void WebModule::Unfreeze(render_tree::ResourceProvider* resource_provider,
+                         SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
   message_loop()->task_runner()->PostTask(
       FROM_HERE, base::Bind(&WebModule::Impl::Unfreeze,
-                            base::Unretained(impl_.get()), resource_provider));
+                            base::Unretained(impl_.get()),
+                            resource_provider, timestamp));
 }
 
-void WebModule::Reveal(render_tree::ResourceProvider* resource_provider) {
+void WebModule::Reveal(render_tree::ResourceProvider* resource_provider,
+                       SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
   message_loop()->task_runner()->PostTask(
       FROM_HERE, base::Bind(&WebModule::Impl::Reveal,
-                            base::Unretained(impl_.get()), resource_provider));
+                            base::Unretained(impl_.get()),
+                            resource_provider, timestamp));
 }
 
-void WebModule::Focus() {
+void WebModule::Focus(SbTimeMonotonic timestamp) {
   // Must only be called by a thread external from the WebModule thread.
   DCHECK_NE(base::MessageLoop::current(), message_loop());
 
   message_loop()->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&WebModule::Impl::Focus, base::Unretained(impl_.get())));
+      base::Bind(&WebModule::Impl::Focus,
+                 base::Unretained(impl_.get()), timestamp));
 }
 
 void WebModule::ReduceMemory() {
diff --git a/src/cobalt/browser/web_module.h b/src/cobalt/browser/web_module.h
index af0b166..d2ebec1 100644
--- a/src/cobalt/browser/web_module.h
+++ b/src/cobalt/browser/web_module.h
@@ -31,6 +31,7 @@
 #include "cobalt/browser/lifecycle_observer.h"
 #include "cobalt/browser/screen_shot_writer.h"
 #include "cobalt/browser/splash_screen_cache.h"
+#include "cobalt/browser/user_agent_platform_info.h"
 #include "cobalt/css_parser/parser.h"
 #include "cobalt/cssom/viewport_size.h"
 #include "cobalt/dom/blob.h"
@@ -210,11 +211,6 @@
     // the frozen state.
     bool should_retain_remote_typeface_cache_on_freeze = false;
 
-    // The language and script to use with fonts. If left empty, then the
-    // language-script combination provided by base::GetSystemLanguageScript()
-    // is used.
-    std::string font_language_script_override;
-
     // The splash screen cache object, owned by the BrowserModule.
     SplashScreenCache* splash_screen_cache;
 
@@ -386,12 +382,15 @@
   }
 
   // LifecycleObserver implementation
-  void Blur() override;
-  void Conceal(render_tree::ResourceProvider* resource_provider) override;
-  void Freeze() override;
-  void Unfreeze(render_tree::ResourceProvider* resource_provider) override;
-  void Reveal(render_tree::ResourceProvider* resource_provider) override;
-  void Focus() override;
+  void Blur(SbTimeMonotonic timestamp) override;
+  void Conceal(render_tree::ResourceProvider* resource_provider,
+               SbTimeMonotonic timestamp) override;
+  void Freeze(SbTimeMonotonic timestamp) override;
+  void Unfreeze(render_tree::ResourceProvider* resource_provider,
+                SbTimeMonotonic timestamp) override;
+  void Reveal(render_tree::ResourceProvider* resource_provider,
+              SbTimeMonotonic timestamp) override;
+  void Focus(SbTimeMonotonic timestamp) override;
 
   // Attempt to reduce overall memory consumption. Called in response to a
   // system indication that memory usage is nearing a critical level.
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 258e9df..6655f86 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-302142
\ No newline at end of file
+303007
\ No newline at end of file
diff --git a/src/cobalt/configuration/configuration.cc b/src/cobalt/configuration/configuration.cc
index 7cde16b..d130c87 100644
--- a/src/cobalt/configuration/configuration.cc
+++ b/src/cobalt/configuration/configuration.cc
@@ -34,7 +34,7 @@
       SbSystemGetExtension(kCobaltExtensionConfigurationName));
   if (configuration_api_) {
     // Verify it's the extension needed.
-    if (SbStringCompareAll(configuration_api_->name,
+    if (strcmp(configuration_api_->name,
                            kCobaltExtensionConfigurationName) != 0 ||
         configuration_api_->version < 1) {
       LOG(WARNING) << "Not using supplied cobalt configuration extension: "
@@ -439,24 +439,6 @@
 #endif
 }
 
-int Configuration::CobaltJsGarbageCollectionThresholdInBytes() {
-  if (configuration_api_) {
-    return configuration_api_->CobaltJsGarbageCollectionThresholdInBytes();
-  }
-#if SB_API_VERSION >= 12
-#if defined(COBALT_JS_GARBAGE_COLLECTION_THRESHOLD_IN_BYTES)
-// NOLINTNEXTLINE(whitespace/line_length)
-#error "COBALT_JS_GARBAGE_COLLECTION_THRESHOLD_IN_BYTES is deprecated after Starboard version 12."
-// NOLINTNEXTLINE(whitespace/line_length)
-#error "Implement CobaltExtensionConfigurationApi::CobaltJsGarbageCollectionThresholdInBytes()"
-#error "instead."
-#endif
-  return 8 * 1024 * 1024;
-#else
-  return 8 * 1024 * 1024;
-#endif
-}
-
 int Configuration::CobaltSkiaGlyphAtlasWidth() {
   if (configuration_api_) {
 #if defined(COBALT_SKIA_GLYPH_ATLAS_WIDTH)
diff --git a/src/cobalt/content/fonts/config/common/fonts.xml b/src/cobalt/content/fonts/config/common/fonts.xml
index 8f84727..abba022 100644
--- a/src/cobalt/content/fonts/config/common/fonts.xml
+++ b/src/cobalt/content/fonts/config/common/fonts.xml
@@ -164,337 +164,337 @@
         <!-- "Noto Naskh Arabic UI" is given a fallback priority so that, in spite
              of having a name, it will still be included as a fallback font.
         -->
-        <family fallback_priority="0" name="Noto Naskh Arabic UI" pages="0,6-8,32,37,46,251-254">
+        <family lang="und-Arab" fallback_priority="0" name="Noto Naskh Arabic UI" pages="0,6-8,32,37,46,251-254">
             <font weight="400" style="normal">NotoNaskhArabicUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoNaskhArabicUI-Bold.woff2</font>
         </family>
-        <family pages="0,18-19,45,171,254">
+        <family lang="und-Ethi" pages="0,18-19,45,171,254">
             <font weight="400" style="normal">NotoSansEthiopic-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansEthiopic-Bold.woff2</font>
         </family>
-        <family pages="0,5,32,37,251,254">
+        <family lang="und-Hebr" pages="0,5,32,37,251,254">
             <font weight="400" style="normal">NotoSansHebrew-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansHebrew-Bold.woff2</font>
         </family>
-        <family pages="0,2-3,14,32,37,254">
+        <family lang="und-Thai" pages="0,2-3,14,32,37,254">
             <font weight="400" style="normal">NotoSansThaiUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansThaiUI-Bold.woff2</font>
         </family>
-        <family pages="0,5,32,251">
+        <family lang="und-Armn" pages="0,5,32,251">
             <font weight="400" style="normal">NotoSansArmenian-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansArmenian-Bold.woff2</font>
         </family>
-        <family pages="0,5,16,45,254">
+        <family lang="und-Geor,und-Geok" pages="0,5,16,45,254">
             <font weight="400" style="normal">NotoSansGeorgian-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansGeorgian-Bold.woff2</font>
         </family>
-        <family pages="0,2,9,28,32,34,37,168,254">
+        <family lang="und-Deva" pages="0,2,9,28,32,34,37,168,254">
             <font weight="400" style="normal">NotoSansDevanagariUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansDevanagariUI-Bold.woff2</font>
         </family>
         <!-- Gujarati should come after Devanagari -->
-        <family pages="0,9-10,32,34,37,168,254">
+        <family lang="und-Gujr" pages="0,9-10,32,34,37,168,254">
             <font weight="400" style="normal">NotoSansGujaratiUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansGujaratiUI-Bold.woff2</font>
         </family>
         <!-- Gurmukhi should come after Devanagari -->
-        <family pages="0,9-10,32,34,37-38,168,254">
+        <family lang="und-Guru" pages="0,9-10,32,34,37-38,168,254">
             <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansGurmukhiUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,11,32,34,37,254">
+        <family lang="und-Taml" pages="0,9,11,32,34,37,254">
             <font weight="400" style="normal">NotoSansTamilUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansTamilUI-Bold.woff2</font>
         </family>
-        <family pages="0,3,9,13,32,34,37,254">
+        <family lang="und-Mlym" pages="0,3,9,13,32,34,37,254">
             <font weight="400" style="normal">NotoSansMalayalamUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansMalayalamUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,32,34,37,254">
+        <family lang="und-Beng" pages="0,9,32,34,37,254">
             <font weight="400" style="normal">NotoSansBengaliUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansBengaliUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,12,32,34,37,254">
+        <family lang="und-Telu" pages="0,9,12,32,34,37,254">
             <font weight="400" style="normal">NotoSansTeluguUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansTeluguUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,12,32,34,37,254">
+        <family lang="und-Knda" pages="0,9,12,32,34,37,254">
             <font weight="400" style="normal">NotoSansKannadaUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansKannadaUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,11,32,34,37,254">
+        <family lang="und-Orya" pages="0,9,11,32,34,37,254">
             <font weight="400" style="normal">NotoSansOriyaUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansOriyaUI-Bold.woff2</font>
         </family>
-        <family pages="0,9,13,32,34,37,254">
+        <family lang="und-Sinh" pages="0,9,13,32,34,37,254">
             <font weight="400" style="normal">NotoSansSinhala-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansSinhala-Bold.woff2</font>
         </family>
-        <family pages="0,23,25,32,37">
+        <family lang="und-Khmr" pages="0,23,25,32,37">
             <font weight="400" style="normal">NotoSansKhmerUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansKhmerUI-Bold.woff2</font>
         </family>
-        <family pages="0,3,14,32,37">
+        <family lang="und-Laoo" pages="0,3,14,32,37">
             <font weight="400" style="normal">NotoSansLaoUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansLaoUI-Bold.woff2</font>
         </family>
-        <family pages="0,16,32,37,169-170,254">
+        <family lang="und-Mymr" pages="0,16,32,37,169-170,254">
             <font weight="400" style="normal">NotoSansMyanmarUI-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansMyanmarUI-Bold.woff2</font>
         </family>
-        <family pages="0,6-7,32,37,253-254">
+        <family lang="und-Thaa" pages="0,6-7,32,37,253-254">
             <font weight="400" style="normal">NotoSansThaana-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansThaana-Bold.woff2</font>
         </family>
-        <family pages="0,3,170">
+        <family lang="und-Cham" pages="0,3,170">
             <font weight="400" style="normal">NotoSansCham-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansCham-Bold.woff2</font>
         </family>
-        <family pages="0,6,32,46,489">
+        <family lang="und-Adlm" pages="0,6,32,46,489">
             <font weight="400" style="normal">NotoSansAdlam-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,32,46,254,267">
+        <family lang="und-Avst" pages="0,32,46,254,267">
             <font weight="400" style="normal">NotoSansAvestan-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,27,32,37,254">
+        <family lang="und-Bali" pages="0,27,32,37,254">
             <font weight="400" style="normal">NotoSansBalinese-Regular.woff2</font>
         </family>
-        <family pages="0,166,254,360-362">
+        <family lang="und-Bamu" pages="0,166,254,360-362">
             <font weight="400" style="normal">NotoSansBamum-Regular.woff2</font>
         </family>
-        <family pages="0,27,254">
+        <family lang="und-Batk" pages="0,27,254">
             <font weight="400" style="normal">NotoSansBatak-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,272">
+        <family lang="und-Brah" pages="0,254,272">
             <font weight="400" style="normal">NotoSansBrahmi-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,26,32,37,169,254">
+        <family lang="und-Bugi" pages="0,26,32,37,169,254">
             <font weight="400" style="normal">NotoSansBuginese-Regular.woff2</font>
         </family>
-        <family pages="0,23,254">
+        <family lang="und-Buhd" pages="0,23,254">
             <font weight="400" style="normal">NotoSansBuhid-Regular.woff2</font>
         </family>
-        <family pages="0-3,20-22,24,254">
+        <family lang="und-Cans" pages="0-3,20-22,24,254">
             <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,258">
+        <family lang="und-Cari" pages="0,254,258">
             <font weight="400" style="normal">NotoSansCarian-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,3,19,171">
+        <family lang="und-Cher" pages="0,3,19,171">
             <font weight="400" style="normal">NotoSansCherokee-Regular.woff2</font>
         </family>
-        <family pages="0,3,29,37,44,254">
+        <family lang="und-Copt" pages="0,3,29,37,44,254">
             <font weight="400" style="normal">NotoSansCoptic-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,288-292">
+        <family lang="und-Xsux" pages="0,254,288-292">
             <font weight="400" style="normal">NotoSansCuneiform-Regular.woff2</font>
         </family>
-        <family pages="0,254,264">
+        <family lang="und-Cprt" pages="0,254,264">
             <font weight="400" style="normal">NotoSansCypriot-Regular.woff2</font>
         </family>
-        <family pages="0,254,260">
+        <family lang="und-Dsrt" pages="0,254,260">
             <font weight="400" style="normal">NotoSansDeseret-Regular.woff2</font>
         </family>
-        <family pages="0,254,304-308">
+        <family lang="und-Egyp" pages="0,254,304-308">
             <font weight="400" style="normal">NotoSansEgyptianHieroglyphs-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,44,254">
+        <family lang="und-Glag" pages="0,44,254">
             <font weight="400" style="normal">NotoSansGlagolitic-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,3,254,259">
+        <family lang="und-Goth" pages="0,3,254,259">
             <font weight="400" style="normal">NotoSansGothic-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,23,254">
+        <family lang="und-Hano" pages="0,23,254">
             <font weight="400" style="normal">NotoSansHanunoo-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,264">
+        <family lang="und-Armi" pages="0,254,264">
             <font weight="400" style="normal">NotoSansImperialAramaic-Regular.woff2</font>
         </family>
-        <family pages="0,254,267">
+        <family lang="und-Phli" pages="0,254,267">
             <font weight="400" style="normal">NotoSansInscriptionalPahlavi-Regular.woff2</font>
         </family>
-        <family pages="0,254,267">
+        <family lang="und-Prti" pages="0,254,267">
             <font weight="400" style="normal">NotoSansInscriptionalParthian-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,32,37,169,254">
+        <family lang="und-Java" pages="0,32,37,169,254">
             <font weight="400" style="normal">NotoSansJavanese-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,9,168,254,272">
+        <family lang="und-Kthi" pages="0,9,168,254,272">
             <font weight="400" style="normal">NotoSansKaithi-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,169,254">
+        <family lang="und-Kali" pages="0,169,254">
             <font weight="400" style="normal">NotoSansKayahLi-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,266">
+        <family lang="und-Khar" pages="0,254,266">
             <font weight="400" style="normal">NotoSansKharoshthi-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,28,37,254">
+        <family lang="und-Lepc" pages="0,28,37,254">
             <font weight="400" style="normal">NotoSansLepcha-Regular.woff2</font>
         </family>
-        <family pages="0,9,25,254">
+        <family lang="und-Limb" pages="0,9,25,254">
             <font weight="400" style="normal">NotoSansLimbu-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,256-257">
+        <family lang="und-Linb" pages="0,254,256-257">
             <font weight="400" style="normal">NotoSansLinearB-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,2,164,254">
+        <family lang="und-Lisu" pages="0,2,164,254">
             <font weight="400" style="normal">NotoSansLisu-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,258">
+        <family lang="und-Lyci" pages="0,254,258">
             <font weight="400" style="normal">NotoSansLycian-Regular.woff2</font>
         </family>
-        <family pages="0,254,265">
+        <family lang="und-Lydi" pages="0,254,265">
             <font weight="400" style="normal">NotoSansLydian-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,6,8,254">
+        <family lang="und-Mand" pages="0,6,8,254">
             <font weight="400" style="normal">NotoSansMandaic-Regular.woff2</font>
         </family>
-        <family pages="0,170-171,254">
+        <family lang="und-Mtei" pages="0,170-171,254">
             <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.woff2</font>
         </family>
-        <family pages="0,25,254">
+        <family lang="und-Talu" pages="0,25,254">
             <font weight="400" style="normal">NotoSansNewTaiLue-Regular.woff2</font>
         </family>
-        <family pages="0,6-7,32,46,253-254">
+        <family lang="und-Nkoo" pages="0,6-7,32,46,253-254">
             <font weight="400" style="normal">NotoSansNKo-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,22,254">
+        <family lang="und-Ogam" pages="0,22,254">
             <font weight="400" style="normal">NotoSansOgham-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,28,254">
+        <family lang="und-Olck" pages="0,28,254">
             <font weight="400" style="normal">NotoSansOlChiki-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,259">
+        <family lang="und-Ital" pages="0,254,259">
             <font weight="400" style="normal">NotoSansOldItalic-Regular.woff2</font>
         </family>
-        <family pages="0,254,259">
+        <family lang="und-Xpeo" pages="0,254,259">
             <font weight="400" style="normal">NotoSansOldPersian-Regular.woff2</font>
         </family>
-        <family pages="0,254,266">
+        <family lang="und-Sarb" pages="0,254,266">
             <font weight="400" style="normal">NotoSansOldSouthArabian-Regular.woff2</font>
         </family>
-        <family pages="0,254,268">
+        <family lang="und-Orkh" pages="0,254,268">
             <font weight="400" style="normal">NotoSansOldTurkic-Regular.woff2</font>
         </family>
-        <family pages="0,254,260">
+        <family lang="und-Osma" pages="0,254,260">
             <font weight="400" style="normal">NotoSansOsmanya-Regular.woff2</font>
         </family>
-        <family pages="0,254,265">
+        <family lang="und-Phnx" pages="0,254,265">
             <font weight="400" style="normal">NotoSansPhoenician-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,169,254">
+        <family lang="und-Rjng" pages="0,169,254">
             <font weight="400" style="normal">NotoSansRejang-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,22,254">
+        <family lang="und-Runr" pages="0,22,254">
             <font weight="400" style="normal">NotoSansRunic-Regular.woff2</font>
         </family>
-        <family pages="0,8,46,254">
+        <family lang="und-Samr" pages="0,8,46,254">
             <font weight="400" style="normal">NotoSansSamaritan-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,32,37,168,254">
+        <family lang="und-Saur" pages="0,32,37,168,254">
             <font weight="400" style="normal">NotoSansSaurashtra-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,254,260">
+        <family lang="und-Shaw" pages="0,254,260">
             <font weight="400" style="normal">NotoSansShavian-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-lang-non-cjk">
-        <family pages="0,27-28,254">
+        <family lang="und-Sund" pages="0,27-28,254">
             <font weight="400" style="normal">NotoSansSundanese-Regular.woff2</font>
         </family>
-        <family pages="0,9,32,37,168,254">
+        <family lang="und-Sylo" pages="0,9,32,37,168,254">
             <font weight="400" style="normal">NotoSansSylotiNagri-Regular.woff2</font>
         </family>
         <!-- Estrangela should precede Eastern and Western Syriac, since it's our default form. -->
-        <family pages="0,3,6-7,32,34,37-38,254">
+        <family lang="und-Syre" pages="0,3,6-7,32,34,37-38,254">
             <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.woff2</font>
         </family>
-        <family pages="0,3,6-7,32,34,37-38,254">
+        <family lang="und-Syrn" pages="0,3,6-7,32,34,37-38,254">
             <font weight="400" style="normal">NotoSansSyriacEastern-Regular.woff2</font>
         </family>
-        <family pages="0,3,6-7,32,34,37-38,254">
+        <family lang="und-Syrj" pages="0,3,6-7,32,34,37-38,254">
             <font weight="400" style="normal">NotoSansSyriacWestern-Regular.woff2</font>
         </family>
-        <family pages="0,23,254">
+        <family lang="und-Tglg" pages="0,23,254">
             <font weight="400" style="normal">NotoSansTagalog-Regular.woff2</font>
         </family>
-        <family pages="0,23,254">
+        <family lang="und-Tagb" pages="0,23,254">
             <font weight="400" style="normal">NotoSansTagbanwa-Regular.woff2</font>
         </family>
-        <family pages="0,26,32,34,37,254">
+        <family lang="und-Lana" pages="0,26,32,34,37,254">
             <font weight="400" style="normal">NotoSansTaiTham-Regular.woff2</font>
         </family>
-        <family pages="0,32,37,167,170,254">
+        <family lang="und-Tavt" pages="0,32,37,167,170,254">
             <font weight="400" style="normal">NotoSansTaiViet-Regular.woff2</font>
         </family>
-        <family pages="0,15,32,37,254">
+        <family lang="und-Tibt" pages="0,15,32,37,254">
             <font weight="400" style="normal">NotoSansTibetan-Regular.woff2</font>
             <font weight="700" style="normal">NotoSansTibetan-Bold.woff2</font>
         </family>
-        <family pages="0,3,32,45,254">
+        <family lang="und-Tfng" pages="0,3,32,45,254">
             <font weight="400" style="normal">NotoSansTifinagh-Regular.woff2</font>
         </family>
     </package>
-    <package name="fallback-historic">
+    <package lang="und-Ugar" name="fallback-historic">
         <family pages="0,254,259">
             <font weight="400" style="normal">NotoSansUgaritic-Regular.woff2</font>
         </family>
     </package>
-    <package name="fallback-lang-non-cjk">
+    <package lang="und-Vaii" name="fallback-lang-non-cjk">
         <family pages="0,165-166,254">
             <font weight="400" style="normal">NotoSansVai-Regular.woff2</font>
         </family>
@@ -519,7 +519,7 @@
         </family>
     </package>
     <package name="fallback-color-emoji">
-        <family pages="0,32-33,35-39,41,43,48,50,496-502,505,3584,4068,4072">
+        <family lang="und-Zsye" pages="0,32-33,35-39,41,43,48,50,496-502,505,3584,4068,4072">
             <font weight="400" style="normal" disable_synthetic_bolding="true">NotoColorEmoji.woff2</font>
         </family>
     </package>
@@ -529,7 +529,7 @@
         </family>
     </package>
     <package name="fallback-symbols">
-        <family pages="35,37-39,43,496-498">
+        <family lang="und-Zsym" pages="35,37-39,43,496-498">
             <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted2.woff2</font>
         </family>
     </package>
@@ -548,18 +548,18 @@
             Tai Le, Yi, Mongolian, and Phags-pa are intentionally kept last, to make sure they don't
             override the East Asian punctuation for Chinese.
         -->
-        <family pages="0,3,16,25,48,254">
+        <family lang="und-Tale" pages="0,3,16,25,48,254">
             <font weight="400" style="normal">NotoSansTaiLe-Regular.woff2</font>
         </family>
-        <family pages="0,48,160-164,254-255">
+        <family lang="und-Yiii" pages="0,48,160-164,254-255">
             <font weight="400" style="normal">NotoSansYi-Regular.woff2</font>
         </family>
-        <family pages="0,24,32,36-37,48,254">
+        <family lang="und-Mong" pages="0,24,32,36-37,48,254">
             <font weight="400" style="normal">NotoSansMongolian-Regular.woff2</font>
         </family>
     </package>
     <package name="fallback-historic">
-        <family pages="0,24,32,37,48,168,254">
+        <family lang="und-Phag" pages="0,24,32,37,48,168,254">
             <font weight="400" style="normal">NotoSansPhagsPa-Regular.woff2</font>
         </family>
     </package>
diff --git a/src/cobalt/css_parser/trivial_string_piece.h b/src/cobalt/css_parser/trivial_string_piece.h
index 1f91641..4c5be8f 100644
--- a/src/cobalt/css_parser/trivial_string_piece.h
+++ b/src/cobalt/css_parser/trivial_string_piece.h
@@ -48,13 +48,13 @@
     const char* c_string) {
   TrivialStringPiece string_piece;
   string_piece.begin = c_string;
-  string_piece.end = c_string + SbStringGetLength(c_string);
+  string_piece.end = c_string + strlen(c_string);
   return string_piece;
 }
 
 // Used by tests.
 inline bool operator==(const TrivialStringPiece& lhs, const char* rhs) {
-  return SbStringCompare(lhs.begin, rhs, lhs.size()) == 0 &&
+  return strncmp(lhs.begin, rhs, lhs.size()) == 0 &&
          rhs[lhs.size()] == '\0';
 }
 
diff --git a/src/cobalt/debug/backend/content/runtime_agent.js b/src/cobalt/debug/backend/content/runtime_agent.js
deleted file mode 100644
index f426e65..0000000
--- a/src/cobalt/debug/backend/content/runtime_agent.js
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This implementation of the "Runtime" Devtools protocol domain is only used
-// for mozjs. When using V8, we use the built-in inspector backend which
-// implements this for us.
-
-(function(debugBackend) {
-
-// Attach methods to handle commands in the 'Runtime' devtools domain.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime
-var commands = debugBackend.Runtime = {};
-
-// Calls a function on a previously accessed RemoteObject with an argument list
-// and returns a new RemoteObject. Used extensively by devtools for
-// auto-completion. The new RemoteObject uses the same |objectGroup| as the
-// original object.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-callFunctionOn
-commands.callFunctionOn = function(params) {
-  var result = {};
-  var value = null;
-  try {
-    eval('var f = ' + params.functionDeclaration);
-    var objectEntry = _objectStore[params.objectId];
-    var thisArg = objectEntry.object;
-    var objectGroup = objectEntry.objectGroup;
-    value = f.apply(thisArg, params.arguments);
-    result.wasThrown = false;
-  } catch(e) {
-    value = e;
-    result.exceptionDetails = e;
-    result.wasThrown = true;
-  }
-
-  result.result =
-      new devtools.RemoteObject(value, objectGroup, params.returnByValue);
-  return JSON.stringify(result);
-}
-
-// Evaluates a string and returns a RemoteObject.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-evaluate
-commands.evaluate = function(params) {
-  var result = {};
-  var value = null;
-  try {
-    if (params.includeCommandLineAPI) {
-      _addCommandLineAPI();
-    }
-
-    // Use |eval| indirectly, to cause evaluation at global scope.
-    // This is so subsequent calls can access variables declared here, etc.
-    var geval = eval;
-    value = geval(params.expression);
-
-    // Store the last result if we're doing a "real" evaluation, not an
-    // auto-complete. Seems a little special case-y, but this is taken from
-    // Chrome's implementation, and looks like the only way to differentiate.
-    if (params.objectGroup == 'console') {
-      _lastResult = value;
-    }
-
-    result.wasThrown = false;
-  } catch(e) {
-    value = e;
-    result.exceptionDetails = e;
-    result.wasThrown = true;
-  }
-
-  // Create the RemoteObject corresponding to the result.
-  result.result =
-      new devtools.RemoteObject(value, params.objectGroup, params.returnByValue);
-
-  // Add the preview, if requested.
-  if (params.generatePreview) {
-    var preview = _generatePreview(value);
-    if (preview) {
-      result.result.preview = preview;
-    }
-  }
-
-  if (params.includeCommandLineAPI) {
-    _removeCommandLineAPI();
-  }
-
-  return JSON.stringify(result);
-}
-
-// Returns all let, const and class variables from global scope.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-globalLexicalScopeNames
-commands.globalLexicalScopeNames = function(params) {
-  var result = [];
-  // TODO: Get the globals.
-  return JSON.stringify(result);
-}
-
-// Returns the properties of a previously accessed object as an array of
-// PropertyDescriptor objects.
-// The parameters specifify several options:
-// * ownProperties - only include immediate properties, not the prototype chain.
-// * accessorPropertiesOnly - only include accessor properties.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-getProperties
-commands.getProperties = function(params) {
-  var result = {};
-  var properties = [];
-  try {
-    var objectEntry = _objectStore[params.objectId];
-    var object = objectEntry.object;
-    var objectGroup = objectEntry.objectGroup;
-    _addProperties(object, objectGroup, !params.ownProperties, properties);
-
-    if (params.accessorPropertiesOnly) {
-      properties = properties.filter(function(element, index, array) {
-          return (element.get || element.set);
-        });
-    }
-    result.wasThrown = false;
-  } catch(e) {
-    value = e;
-    result.exceptionDetails = e;
-    result.wasThrown = true;
-  }
-
-  result.result = properties;
-  return JSON.stringify(result);
-}
-
-// Releases our reference to a previously accessed object.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-releaseObject
-commands.releaseObject = function(params) {
-  delete _objectStore[params.objectId];
-}
-
-// Releases our references to a group of previously accessed objects.
-// https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#method-releaseObjectGroup
-commands.releaseObjectGroup = function(params) {
-  for (var objectId in _objectStore) {
-    var objectEntry = _objectStore[objectId];
-    if (objectEntry && objectEntry.objectGroup == params.objectGroup) {
-      delete _objectStore[objectId];
-    }
-  }
-}
-
-// Adds the properties of |object| to the |result| array as new
-// PropertyDescriptor objects. Some properties may be objects themselves,
-// in which case new RemoteObjects are created using the specified
-// |objectGroup|, which should be that of |object|.
-// If |includePrototype| is set, the function will be called recursively on
-// the prototype chain of the object.
-var _addProperties = function(object, objectGroup, includePrototype, result) {
-  var properties = Object.getOwnPropertyNames(object);
-  var foundProto = false;
-  for (var i = 0; i < properties.length; i++) {
-    var key = properties[i];
-    foundProto = foundProto || (key == '__proto__');
-
-    // If we can't find the property, and its name corresponds to a number,
-    // try it as an array index (integer instead of string).
-    if (object[key] == null) {
-      if (!isNaN(key)) {
-        key = parseInt(key);
-      } else {
-        continue;
-      }
-    }
-
-    var propertyDescriptor =
-        new devtools.PropertyDescriptor(object, objectGroup, key);
-    result.push(propertyDescriptor);
-  }
-
-  var proto = null;
-  try {
-    proto = Object.getPrototypeOf(object);
-  } catch (e) {}
-
-  if (includePrototype) {
-    // Recursively add the properties from the prototype chain.
-    if (proto) {
-      _addProperties(proto, objectGroup, includePrototype, result);
-    }
-  } else if (proto && !foundProto) {
-    // |getOwnPropertyNames| may not include the object prototype,
-    // so if that's the case, add it now. It's a deprecated name, but devtools
-    // still uses it.
-    var propertyDescriptor =
-        new devtools.PropertyDescriptor(object, objectGroup, '__proto__');
-    result.push(propertyDescriptor);
-  }
-}
-
-// Gets an object from the internal object store.
-var _getObject = function(objectId) {
-  return _objectStore[objectId].object;
-}
-
-// Adds an object to the internal object store and returns a unique id that can
-// be used to access it again.
-var _addObject = function(object, objectGroup) {
-  // If we've already added this object, then use the same objectId.
-  for (var objectId in _objectStore) {
-    var objectEntry = _objectStore[objectId];
-    if (objectEntry.object === object &&
-        objectEntry.objectGroup == objectGroup) {
-      return objectId;
-    }
-  }
-
-  var objectId = _nextObjectId.toString();
-  _nextObjectId += 1;
-  _objectStore[objectId] = {};
-  _objectStore[objectId].object = object;
-  _objectStore[objectId].objectGroup = objectGroup;
-  return objectId;
-}
-
-// Generates an object preview, which may be requested for the evaluate
-// command.
-var _generatePreview = function(object) {
-  if (!object || (typeof object != 'object')) {
-    return null;
-  } else {
-    return new devtools.ObjectPreview(object);
-  }
-}
-
-// Returns the subtype of an object, or null if the specified value is not an
-// object.
-var _getSubtype = function(object) {
-  if (typeof object == 'object') {
-    if (object instanceof Array) {
-      return 'array';
-    } else if (object instanceof Date) {
-      return 'date';
-    } else if (object instanceof Error) {
-      return 'error';
-    } else if (object instanceof Node) {
-      return 'node';
-    } else if (object instanceof RegExp) {
-      return 'regexp';
-    }
-  }
-  return null;
-}
-
-// Tries to get the classname of an object by following the prototype chain
-// and looking for a constructor.
-var _getClassName = function(object) {
-  try {
-    for (var obj = object; obj && !this.className;
-         obj = Object.getPrototypeOf(obj)) {
-      if (obj.constructor) {
-        return obj.constructor.name;
-      }
-    }
-  } catch(e) {}
-
-  return null;
-}
-
-// Namespace for constructors of types defined in the Devtools protocol.
-var devtools = {};
-
-// Creates a RemoteObject, which is the type used to return many values to
-// devtools. If |value| is an object, then is it inserted into |_objectStore|
-// and the |objectId| key used to access it is included in the RemoteObject. If
-// |value| is not an object, or |returnByValue| is true, then |value| is
-// directly included in the RemoteObject.
-devtools.RemoteObject = function(value, objectGroup, returnByValue) {
-  this.type = typeof value;
-
-  if (value == null) {
-    this.subtype == 'null';
-    this.value = null;
-    return;
-  }
-
-  if (this.type == 'object') {
-    this.objectId = _addObject(value, objectGroup);
-    this.subtype = _getSubtype(value);
-    this.className = _getClassName(value);
-  }
-
-  // Fill in the description field. Devtools will only display arrays correctly
-  // if their description follows a particular format. For other values, try to
-  // use the generic string conversion, and fall back to the className if that
-  // fails.
-  if (this.subtype == 'array') {
-    this.description = 'Array[' + value.length + ']';
-  } else {
-    try {
-      this.description = value.toString();
-    } catch(e) {
-      this.description = this.className;
-    }
-  }
-
-  if (returnByValue || this.type != 'object') {
-    this.value = value;
-  }
-}
-
-// Creates a PropertyDescriptor for |property| of |object|, which is the type
-// used to return object properties to devtools. Some properties may be objects,
-// in which case new RemoteObjects are created and inserted into |_objectStore|
-// using the specified |objectGroup|, which should be that of |object|.
-devtools.PropertyDescriptor = function(object, objectGroup, property) {
-  this.name = property.toString();
-  var descriptor = Object.getOwnPropertyDescriptor(object, property);
-  // Some Cobalt objects don't seem to support |getOwnPropertyDescriptor|,
-  // so we handle that case in the else clause below.
-  if (descriptor) {
-    this.configurable = descriptor.configurable;
-    this.enumerable = descriptor.enumerable;
-    if (descriptor.get) {
-      this.get = new devtools.RemoteObject(descriptor.get, objectGroup, false);
-    }
-    if (descriptor.set) {
-      this.set = new devtools.RemoteObject(descriptor.set, objectGroup, false);
-    }
-    if (descriptor.value != null) {
-      this.value =
-          new devtools.RemoteObject(descriptor.value, objectGroup, false);
-    }
-    this.writable = descriptor.writable;
-  } else if (object[property] != null) {
-    this.configurable = false;
-    this.enumerable = object.propertyIsEnumerable(property);
-    if (object.__lookupGetter__(property)) {
-      this.get = object.__lookupGetter__(property);
-    }
-    if (object.__lookupSetter__(property)) {
-      this.set = object.__lookupSetter__(property);
-    }
-    this.value =
-        new devtools.RemoteObject(object[property], objectGroup, false);
-  }
-}
-
-// Creates an ObjectPreview, the type to represent a preview of an object,
-// which may be requested by devtools in the evaluate command.
-devtools.ObjectPreview = function(value) {
-  this.type = typeof value;
-  this.subtype = _getSubtype(value);
-  this.lossless = true;
-  this.overflow = false;
-  this.properties = [];
-
-  // Use the className as the preview description. This matches Chrome.
-  this.description = _getClassName(value);
-
-  // If we have an array-like object, add the array items, or append the
-  // length to the description if there's too many.
-  if (value.length != null) {
-    var MAX_ARRAY_ITEMS = 99;
-    if (value.length <= MAX_ARRAY_ITEMS) {
-      for (var i = 0; i < value.length; i++) {
-        var property = new devtools.PropertyPreview(i, value[i]);
-        this.properties.push(property);
-        if (typeof value[i] == 'object') {
-          this.lossless = false;
-        }
-      }
-    } else {
-      this.description += '[' + value.length + ']';
-      this.lossless = false;
-      this.overflow = true;
-    }
-    return;
-  }
-
-  // Add object properties, up to a maximum.
-  var MAX_PROPERTIES = 5;
-  var numProperties = 0;
-  for (var name in value) {
-    if (value[name] != null) {
-      if (++numProperties > MAX_PROPERTIES) {
-        this.lossless = false;
-        this.overflow = true;
-        break;
-      }
-      if (typeof property == 'object') {
-        this.lossless = false;
-      }
-      var property = new devtools.PropertyPreview(name, value[name]);
-      this.properties.push(property);
-    }
-  }
-}
-
-// Creates a PropertyPreview, the type to represent a preview of a single
-// object property.
-devtools.PropertyPreview = function(name, value) {
-  this.name = name.toString();
-  this.type = typeof value;
-
-  try {
-    this.value = value.toString();
-  } catch(e) {}
-
-  if (this.type == 'object') {
-    this.subtype = _getSubtype(value);
-  }
-}
-
-// The object store used to reference objects by internally generated id.
-var _objectStore = {};
-var _nextObjectId = 0;
-
-// The last evaluated result.
-var _lastResult = null;
-
-// Values in the global scope that have been overridden by corresponding
-// members of the Command Line API for the duration of an evaluation. We use
-// this to restore the original values after the evaluation.
-var _globalOverrides = {};
-
-// Command Line API implementation.
-// This is a set of convenience variables/functions that are not present in
-// the global scope by default, but can be specified as available to the
-// Runtime.evaluate function by the includeCommandLineAPI parameter.
-// https://developers.google.com/web/tools/chrome-devtools/console/utilities
-var _commandLineAPI = {};
-
-_commandLineAPI.$_ = _lastResult;
-
-_commandLineAPI.$ = document.querySelector.bind(document);
-
-_commandLineAPI.$$ = document.querySelectorAll.bind(document);
-
-_commandLineAPI.keys = Object.keys;
-
-_commandLineAPI.values = function(object) {
-  var keys = Object.keys(object);
-  var result = [];
-  for (var i = 0; i < keys.length; i++) {
-    result.push(object[keys[i]]);
-  }
-  return result;
-}
-
-var _addCommandLineAPI = function() {
-  _commandLineAPI.$_ = _lastResult;
-  for (var property in _commandLineAPI) {
-    if (_commandLineAPI.hasOwnProperty(property)) {
-      _globalOverrides[property] = window[property];
-      window[property] = _commandLineAPI[property];
-    }
-  }
-}
-
-var _removeCommandLineAPI = function() {
-  for (var property in _globalOverrides) {
-    if (_globalOverrides.hasOwnProperty(property)) {
-      window[property] = _globalOverrides[property];
-      delete _globalOverrides[property];
-    }
-  }
-}
-
-// TODO: Pass debugBackend from C++ instead of getting it from the window.
-})(window.debugBackend);
diff --git a/src/cobalt/debug/backend/debug_module.cc b/src/cobalt/debug/backend/debug_module.cc
index 1c64b86..a7fe6ab 100644
--- a/src/cobalt/debug/backend/debug_module.cc
+++ b/src/cobalt/debug/backend/debug_module.cc
@@ -24,7 +24,6 @@
 
 namespace {
 constexpr char kScriptDebuggerAgent[] = "ScriptDebuggerAgent";
-constexpr char kRuntimeAgent[] = "RuntimeAgent";
 constexpr char kLogAgent[] = "LogAgent";
 constexpr char kDomAgent[] = "DomAgent";
 constexpr char kCssAgent[] = "CssAgent";
@@ -158,10 +157,6 @@
   // directly handle one or more protocol domains.
   script_debugger_agent_.reset(
       new ScriptDebuggerAgent(debug_dispatcher_.get(), script_debugger_.get()));
-  if (!script_debugger_agent_->IsSupportedDomain("Runtime")) {
-    runtime_agent_.reset(
-        new RuntimeAgent(debug_dispatcher_.get(), data.window));
-  }
   log_agent_.reset(new LogAgent(debug_dispatcher_.get()));
   dom_agent_.reset(new DOMAgent(debug_dispatcher_.get()));
   css_agent_ = WrapRefCounted(new CSSAgent(debug_dispatcher_.get()));
@@ -191,9 +186,6 @@
                                      : data.debugger_state->agents_state.get();
   script_debugger_agent_->Thaw(
       RemoveAgentState(kScriptDebuggerAgent, agents_state));
-  if (runtime_agent_) {
-    runtime_agent_->Thaw(RemoveAgentState(kRuntimeAgent, agents_state));
-  }
   log_agent_->Thaw(RemoveAgentState(kLogAgent, agents_state));
   dom_agent_->Thaw(RemoveAgentState(kDomAgent, agents_state));
   css_agent_->Thaw(RemoveAgentState(kCssAgent, agents_state));
@@ -218,9 +210,6 @@
   base::DictionaryValue* agents_state = debugger_state->agents_state.get();
   StoreAgentState(agents_state, kScriptDebuggerAgent,
                   script_debugger_agent_->Freeze());
-  if (runtime_agent_) {
-    StoreAgentState(agents_state, kRuntimeAgent, runtime_agent_->Freeze());
-  }
   StoreAgentState(agents_state, kLogAgent, log_agent_->Freeze());
   StoreAgentState(agents_state, kDomAgent, dom_agent_->Freeze());
   StoreAgentState(agents_state, kCssAgent, css_agent_->Freeze());
diff --git a/src/cobalt/debug/backend/debug_module.h b/src/cobalt/debug/backend/debug_module.h
index 44af6b7..2e3aa91 100644
--- a/src/cobalt/debug/backend/debug_module.h
+++ b/src/cobalt/debug/backend/debug_module.h
@@ -31,7 +31,6 @@
 #include "cobalt/debug/backend/overlay_agent.h"
 #include "cobalt/debug/backend/page_agent.h"
 #include "cobalt/debug/backend/render_overlay.h"
-#include "cobalt/debug/backend/runtime_agent.h"
 #include "cobalt/debug/backend/script_debugger_agent.h"
 #include "cobalt/debug/backend/tracing_agent.h"
 #include "cobalt/debug/json_object.h"
@@ -141,7 +140,6 @@
   scoped_refptr<CSSAgent> css_agent_;
   std::unique_ptr<OverlayAgent> overlay_agent_;
   std::unique_ptr<PageAgent> page_agent_;
-  std::unique_ptr<RuntimeAgent> runtime_agent_;
   std::unique_ptr<ScriptDebuggerAgent> script_debugger_agent_;
   std::unique_ptr<TracingAgent> tracing_agent_;
 };
diff --git a/src/cobalt/debug/backend/runtime_agent.cc b/src/cobalt/debug/backend/runtime_agent.cc
deleted file mode 100644
index 84f8c1a..0000000
--- a/src/cobalt/debug/backend/runtime_agent.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/debug/backend/runtime_agent.h"
-
-#include <string>
-
-#include "base/bind.h"
-
-namespace cobalt {
-namespace debug {
-namespace backend {
-
-RuntimeAgent::RuntimeAgent(DebugDispatcher* dispatcher, dom::Window* window)
-    : AgentBase("Runtime", "runtime_agent.js", dispatcher), window_(window) {
-  commands_["compileScript"] =
-      base::Bind(&RuntimeAgent::CompileScript, base::Unretained(this));
-}
-
-bool RuntimeAgent::DoEnable(Command* command) {
-  if (!AgentBase::DoEnable(command)) return false;
-
-  // Send an executionContextCreated event.
-  // https://chromedevtools.github.io/devtools-protocol/1-3/Runtime#event-executionContextCreated
-  JSONObject params(new base::DictionaryValue());
-  params->SetInteger("context.id", 1);
-  params->SetString("context.origin", window_->location()->origin());
-  params->SetString("context.name", "Cobalt");
-  params->SetBoolean("context.auxData.isDefault", true);
-  dispatcher_->SendEvent(domain_ + ".executionContextCreated", params);
-  return true;
-}
-
-void RuntimeAgent::CompileScript(Command command) {
-  if (!EnsureEnabled(&command)) return;
-
-  // TODO: Parse the JS without eval-ing it... This is to support:
-  // a) Multi-line input from the devtools console
-  // b) https://developers.google.com/web/tools/chrome-devtools/snippets
-  command.SendResponse();
-}
-
-}  // namespace backend
-}  // namespace debug
-}  // namespace cobalt
diff --git a/src/cobalt/debug/backend/runtime_agent.h b/src/cobalt/debug/backend/runtime_agent.h
deleted file mode 100644
index 1e5b5be..0000000
--- a/src/cobalt/debug/backend/runtime_agent.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DEBUG_BACKEND_RUNTIME_AGENT_H_
-#define COBALT_DEBUG_BACKEND_RUNTIME_AGENT_H_
-
-#include "cobalt/debug/backend/agent_base.h"
-#include "cobalt/debug/backend/debug_dispatcher.h"
-#include "cobalt/debug/command.h"
-#include "cobalt/debug/json_object.h"
-#include "cobalt/dom/window.h"
-
-namespace cobalt {
-namespace debug {
-namespace backend {
-
-// Implements a small part of the the "Runtime" inspector protocol domain with
-// just enough to support console input. When using the V8 JavaScript engine,
-// this class is not needed since the V8 inspector implements the Runtime domain
-// for us.
-//
-// https://chromedevtools.github.io/devtools-protocol/tot/Runtime
-class RuntimeAgent : public AgentBase {
- public:
-  RuntimeAgent(DebugDispatcher* dispatcher, dom::Window* window);
-
- private:
-  void CompileScript(Command command);
-
-  bool DoEnable(Command* command) override;
-
-  dom::Window* window_;
-};
-
-}  // namespace backend
-}  // namespace debug
-}  // namespace cobalt
-
-#endif  // COBALT_DEBUG_BACKEND_RUNTIME_AGENT_H_
diff --git a/src/cobalt/debug/debug.gyp b/src/cobalt/debug/debug.gyp
index a0b5407..75b9bec 100644
--- a/src/cobalt/debug/debug.gyp
+++ b/src/cobalt/debug/debug.gyp
@@ -48,8 +48,6 @@
         'backend/render_layer.h',
         'backend/render_overlay.cc',
         'backend/render_overlay.h',
-        'backend/runtime_agent.cc',
-        'backend/runtime_agent.h',
         'backend/script_debugger_agent.cc',
         'backend/script_debugger_agent.h',
         'backend/tracing_agent.cc',
diff --git a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp b/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
deleted file mode 100644
index 39ad8b2..0000000
--- a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
+++ /dev/null
@@ -1,476 +0,0 @@
-front_end/network/network.js
-front_end/network/SignedExchangeInfoView.js
-front_end/network/ResourceWebSocketFrameView.js
-front_end/network/RequestTimingView.js
-front_end/network/RequestResponseView.js
-front_end/network/RequestPreviewView.js
-front_end/network/RequestInitiatorView.js
-front_end/network/RequestHeadersView.js
-front_end/network/RequestHTMLView.js
-front_end/network/RequestCookiesView.js
-front_end/network/NetworkWaterfallColumn.js
-front_end/network/NetworkTimeCalculator.js
-front_end/network/NetworkSearchScope.js
-front_end/network/NetworkPanel.js
-front_end/network/NetworkOverview.js
-front_end/network/NetworkManageCustomHeadersView.js
-front_end/network/NetworkLogViewColumns.js
-front_end/network/NetworkLogView.js
-front_end/network/NetworkItemView.js
-front_end/network/NetworkFrameGrouper.js
-front_end/network/NetworkDataGridNode.js
-front_end/network/NetworkConfigView.js
-front_end/network/HARWriter.js
-front_end/network/EventSourceMessagesView.js
-front_end/network/BlockedURLsPane.js
-front_end/network/BinaryResourceView.js
-front_end/test_runner/test_runner.js
-front_end/test_runner/TestRunner.js
-front_end/emulation/emulation.js
-front_end/emulation/SensorsView.js
-front_end/emulation/MediaQueryInspector.js
-front_end/emulation/InspectedPagePlaceholder.js
-front_end/emulation/GeolocationsSettingsTab.js
-front_end/emulation/EmulatedDevices.js
-front_end/emulation/DevicesSettingsTab.js
-front_end/emulation/DeviceModeWrapper.js
-front_end/emulation/DeviceModeView.js
-front_end/emulation/DeviceModeToolbar.js
-front_end/emulation/DeviceModeModel.js
-front_end/emulation/AdvancedApp.js
-front_end/inspector_main/inspector_main.js
-front_end/inspector_main/RenderingOptions.js
-front_end/inspector_main/InspectorMain.js
-front_end/js_main/js_main.js
-front_end/js_main/JsMain.js
-front_end/search/search.js
-front_end/search/SearchView.js
-front_end/search/SearchResultsPane.js
-front_end/search/SearchConfig.js
-front_end/screencast/screencast.js
-front_end/screencast/ScreencastView.js
-front_end/screencast/ScreencastApp.js
-front_end/screencast/InputModel.js
-front_end/performance_monitor/performance_monitor.js
-front_end/performance_monitor/PerformanceMonitor.js
-front_end/main/main.js
-front_end/main/SimpleApp.js
-front_end/main/MainImpl.js
-front_end/main/ExecutionContextSelector.js
-front_end/snippets/snippets.js
-front_end/snippets/SnippetsQuickOpen.js
-front_end/snippets/ScriptSnippetFileSystem.js
-front_end/settings/settings.js
-front_end/settings/SettingsScreen.js
-front_end/settings/FrameworkBlackboxSettingsTab.js
-front_end/security/security.js
-front_end/security/SecurityPanel.js
-front_end/security/SecurityModel.js
-front_end/javascript_metadata/javascript_metadata.js
-front_end/javascript_metadata/NativeFunctions.js
-front_end/javascript_metadata/JavaScriptMetadata.js
-front_end/har_importer/har_importer.js
-front_end/har_importer/HARImporter.js
-front_end/har_importer/HARFormat.js
-front_end/browser_debugger/browser_debugger.js
-front_end/browser_debugger/XHRBreakpointsSidebarPane.js
-front_end/browser_debugger/ObjectEventListenersSidebarPane.js
-front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
-front_end/browser_debugger/DOMBreakpointsSidebarPane.js
-front_end/layer_viewer/layer_viewer.js
-front_end/layer_viewer/TransformController.js
-front_end/layer_viewer/PaintProfilerView.js
-front_end/layer_viewer/Layers3DView.js
-front_end/layer_viewer/LayerViewHost.js
-front_end/layer_viewer/LayerTreeOutline.js
-front_end/layer_viewer/LayerDetailsView.js
-front_end/cm_web_modes/cm_web_modes.js
-front_end/cm_web_modes/cm_web_modes_cm.js
-front_end/cm_web_modes/cm_web_modes_headless.js
-front_end/cm_web_modes/css.js
-front_end/cm_web_modes/javascript.js
-front_end/cm_web_modes/xml.js
-front_end/cm_web_modes/htmlmixed.js
-front_end/cm_web_modes/htmlembedded.js
-front_end/text_editor/text_editor.js
-front_end/text_editor/TextEditorAutocompleteController.js
-front_end/text_editor/CodeMirrorUtils.js
-front_end/text_editor/CodeMirrorTextEditor.js
-front_end/quick_open/quick_open.js
-front_end/quick_open/QuickOpen.js
-front_end/quick_open/HelpQuickOpen.js
-front_end/quick_open/FilteredListWidget.js
-front_end/quick_open/CommandMenu.js
-front_end/elements/elements.js
-front_end/elements/elements-legacy.js
-front_end/elements/StylesSidebarPane.js
-front_end/elements/StylePropertyTreeElement.js
-front_end/elements/StylePropertyHighlighter.js
-front_end/elements/PropertiesWidget.js
-front_end/elements/PlatformFontsWidget.js
-front_end/elements/NodeStackTraceWidget.js
-front_end/elements/MetricsSidebarPane.js
-front_end/elements/MarkerDecorator.js
-front_end/elements/InspectElementModeController.js
-front_end/elements/EventListenersWidget.js
-front_end/elements/ElementsTreeOutline.js
-front_end/elements/ElementsTreeElement.js
-front_end/elements/ElementsTreeElementHighlighter.js
-front_end/elements/ElementStatePaneWidget.js
-front_end/elements/ElementsSidebarPane.js
-front_end/elements/ElementsPanel.js
-front_end/elements/ElementsBreadcrumbs.js
-front_end/elements/DOMPath.js
-front_end/elements/DOMLinkifier.js
-front_end/elements/ComputedStyleWidget.js
-front_end/elements/ComputedStyleModel.js
-front_end/elements/ColorSwatchPopoverIcon.js
-front_end/elements/ClassesPaneWidget.js
-front_end/timeline_model/timeline_model.js
-front_end/timeline_model/TracingLayerTree.js
-front_end/timeline_model/TimelineProfileTree.js
-front_end/timeline_model/TimelineModel.js
-front_end/timeline_model/TimelineModelFilter.js
-front_end/timeline_model/TimelineJSProfile.js
-front_end/timeline_model/TimelineIRModel.js
-front_end/timeline_model/TimelineFrameModel.js
-front_end/help/help.js
-front_end/help/ReleaseNoteView.js
-front_end/help/ReleaseNoteText.js
-front_end/help/HelpImpl.js
-front_end/workspace_diff/workspace_diff.js
-front_end/workspace_diff/WorkspaceDiff.js
-front_end/mobile_throttling/mobile_throttling.js
-front_end/mobile_throttling/ThrottlingSettingsTab.js
-front_end/mobile_throttling/ThrottlingPresets.js
-front_end/mobile_throttling/ThrottlingManager.js
-front_end/mobile_throttling/NetworkThrottlingSelector.js
-front_end/mobile_throttling/NetworkPanelIndicator.js
-front_end/mobile_throttling/MobileThrottlingSelector.js
-front_end/event_listeners/event_listeners.js
-front_end/event_listeners/EventListenersView.js
-front_end/event_listeners/EventListenersUtils.js
-front_end/object_ui/object_ui.js
-front_end/object_ui/RemoteObjectPreviewFormatter.js
-front_end/object_ui/ObjectPropertiesSection.js
-front_end/object_ui/ObjectPopoverHelper.js
-front_end/object_ui/JavaScriptREPL.js
-front_end/object_ui/JavaScriptAutocomplete.js
-front_end/object_ui/CustomPreviewComponent.js
-front_end/cookie_table/cookie_table.js
-front_end/cookie_table/CookiesTable.js
-front_end/cm_modes/cm_modes.js
-front_end/cm_modes/DefaultCodeMirrorMimeMode.js
-front_end/cm_modes/clike.js
-front_end/cm_modes/coffeescript.js
-front_end/cm_modes/php.js
-front_end/cm_modes/python.js
-front_end/cm_modes/shell.js
-front_end/cm_modes/livescript.js
-front_end/cm_modes/markdown.js
-front_end/cm_modes/clojure.js
-front_end/cm_modes/jsx.js
-front_end/css_overview/css_overview.js
-front_end/css_overview/CSSOverviewUnusedDeclarations.js
-front_end/css_overview/CSSOverviewStartView.js
-front_end/css_overview/CSSOverviewSidebarPanel.js
-front_end/css_overview/CSSOverviewProcessingView.js
-front_end/css_overview/CSSOverviewPanel.js
-front_end/css_overview/CSSOverviewModel.js
-front_end/css_overview/CSSOverviewController.js
-front_end/css_overview/CSSOverviewCompletedView.js
-front_end/console/console.js
-front_end/console/ConsoleContextSelector.js
-front_end/console/ConsoleFilter.js
-front_end/console/ConsoleSidebar.js
-front_end/console/ConsolePanel.js
-front_end/console/ConsolePinPane.js
-front_end/console/ConsolePrompt.js
-front_end/console/ConsoleView.js
-front_end/console/ConsoleViewMessage.js
-front_end/console/ConsoleViewport.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/XMLView.js
-front_end/source_frame/SourcesTextEditor.js
-front_end/source_frame/SourceFrame.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/SourceCodeDiff.js
-front_end/source_frame/ResourceSourceFrame.js
-front_end/source_frame/PreviewFactory.js
-front_end/source_frame/JSONView.js
-front_end/source_frame/ImageView.js
-front_end/source_frame/FontView.js
-front_end/source_frame/BinaryResourceViewFactory.js
-front_end/inline_editor/inline_editor.js
-front_end/inline_editor/SwatchPopoverHelper.js
-front_end/inline_editor/CSSShadowModel.js
-front_end/inline_editor/CSSShadowEditor.js
-front_end/inline_editor/ColorSwatch.js
-front_end/inline_editor/BezierUI.js
-front_end/inline_editor/BezierEditor.js
-front_end/diff/diff.js
-front_end/diff/diff_match_patch.js
-front_end/diff/DiffWrapper.js
-front_end/formatter/formatter.js
-front_end/formatter/ScriptFormatter.js
-front_end/formatter/FormatterWorkerPool.js
-front_end/color_picker/color_picker.js
-front_end/color_picker/Spectrum.js
-front_end/color_picker/ContrastOverlay.js
-front_end/color_picker/ContrastInfo.js
-front_end/color_picker/ContrastDetails.js
-front_end/cm/cm.js
-front_end/cm/active-line.js
-front_end/cm/brace-fold.js
-front_end/cm/closebrackets.js
-front_end/cm/codemirror.js
-front_end/cm/comment.js
-front_end/cm/foldcode.js
-front_end/cm/foldgutter.js
-front_end/cm/mark-selection.js
-front_end/cm/matchbrackets.js
-front_end/cm/multiplex.js
-front_end/cm/overlay.js
-front_end/formatter_worker.unbundled.js
-front_end/heap_snapshot_worker.unbundled.js
-front_end/heap_snapshot_model/heap_snapshot_model.js
-front_end/heap_snapshot_model/HeapSnapshotModel.js
-front_end/heap_snapshot_worker/heap_snapshot_worker.js
-front_end/heap_snapshot_worker/AllocationProfile.js
-front_end/heap_snapshot_worker/HeapSnapshot.js
-front_end/heap_snapshot_worker/HeapSnapshotLoader.js
-front_end/heap_snapshot_worker/HeapSnapshotWorker.js
-front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
-front_end/text_utils/text_utils.js
-front_end/text_utils/TextUtils.js
-front_end/text_utils/TextRange.js
-front_end/text_utils/Text.js
-front_end/formatter_worker/formatter_worker.js
-front_end/formatter_worker/RelaxedJSONParser.js
-front_end/formatter_worker/JavaScriptOutline.js
-front_end/formatter_worker/JavaScriptFormatter.js
-front_end/formatter_worker/IdentityFormatter.js
-front_end/formatter_worker/HTMLFormatter.js
-front_end/formatter_worker/FormatterWorker.js
-front_end/formatter_worker/FormattedContentBuilder.js
-front_end/formatter_worker/ESTreeWalker.js
-front_end/formatter_worker/CSSRuleParser.js
-front_end/formatter_worker/CSSFormatter.js
-front_end/formatter_worker/AcornTokenizer.js
-front_end/cm_headless/cm_headless.js
-front_end/cm_headless/headlesscodemirror.js
-front_end/data_grid/data_grid.js
-front_end/data_grid/ViewportDataGrid.js
-front_end/data_grid/SortableDataGrid.js
-front_end/data_grid/ShowMoreDataGridNode.js
-front_end/data_grid/DataGrid.js
-front_end/protocol_monitor/protocol_monitor.js
-front_end/protocol_monitor/ProtocolMonitor.js
-front_end/console_counters/console_counters.js
-front_end/console_counters/WarningErrorCounter.js
-front_end/extensions/extensions.js
-front_end/extensions/ExtensionAPI.js
-front_end/extensions/ExtensionPanel.js
-front_end/extensions/ExtensionServer.js
-front_end/extensions/ExtensionTraceProvider.js
-front_end/extensions/ExtensionView.js
-front_end/browser_sdk/browser_sdk.js
-front_end/browser_sdk/LogManager.js
-front_end/persistence/persistence.js
-front_end/persistence/WorkspaceSettingsTab.js
-front_end/persistence/PlatformFileSystem.js
-front_end/persistence/PersistenceUtils.js
-front_end/persistence/PersistenceImpl.js
-front_end/persistence/PersistenceActions.js
-front_end/persistence/NetworkPersistenceManager.js
-front_end/persistence/IsolatedFileSystemManager.js
-front_end/persistence/IsolatedFileSystem.js
-front_end/persistence/FileSystemWorkspaceBinding.js
-front_end/persistence/EditFileSystemView.js
-front_end/persistence/Automapping.js
-front_end/components/components.js
-front_end/components/TargetDetachedDialog.js
-front_end/components/Reload.js
-front_end/components/Linkifier.js
-front_end/components/JSPresentationUtils.js
-front_end/components/ImagePreview.js
-front_end/components/DockController.js
-front_end/bindings/bindings.js
-front_end/bindings/TempFile.js
-front_end/bindings/StylesSourceMapping.js
-front_end/bindings/SASSSourceMapping.js
-front_end/bindings/ResourceUtils.js
-front_end/bindings/ResourceScriptMapping.js
-front_end/bindings/ResourceMapping.js
-front_end/bindings/PresentationConsoleMessageHelper.js
-front_end/bindings/NetworkProject.js
-front_end/bindings/LiveLocation.js
-front_end/bindings/FileUtils.js
-front_end/bindings/DefaultScriptMapping.js
-front_end/bindings/DebuggerWorkspaceBinding.js
-front_end/bindings/CSSWorkspaceBinding.js
-front_end/bindings/ContentProviderBasedProject.js
-front_end/bindings/CompilerScriptMapping.js
-front_end/bindings/BreakpointManager.js
-front_end/bindings/BlackboxManager.js
-front_end/workspace/workspace.js
-front_end/workspace/WorkspaceImpl.js
-front_end/workspace/UISourceCode.js
-front_end/workspace/FileManager.js
-front_end/services/services.js
-front_end/services/ServiceManager.js
-front_end/sdk/sdk.js
-front_end/sdk/TracingModel.js
-front_end/sdk/TracingManager.js
-front_end/sdk/TargetManager.js
-front_end/sdk/Target.js
-front_end/sdk/SourceMapManager.js
-front_end/sdk/SourceMap.js
-front_end/sdk/ServiceWorkerManager.js
-front_end/sdk/ServiceWorkerCacheModel.js
-front_end/sdk/ServerTiming.js
-front_end/sdk/SecurityOriginManager.js
-front_end/sdk/SDKModel.js
-front_end/sdk/Script.js
-front_end/sdk/ScreenCaptureModel.js
-front_end/sdk/RuntimeModel.js
-front_end/sdk/ResourceTreeModel.js
-front_end/sdk/Resource.js
-front_end/sdk/RemoteObject.js
-front_end/sdk/ProfileTreeModel.js
-front_end/sdk/IssuesModel.js
-front_end/sdk/PerformanceMetricsModel.js
-front_end/sdk/PaintProfiler.js
-front_end/sdk/OverlayModel.js
-front_end/sdk/NetworkRequest.js
-front_end/sdk/NetworkManager.js
-front_end/sdk/NetworkLog.js
-front_end/sdk/LogModel.js
-front_end/sdk/LayerTreeBase.js
-front_end/sdk/IsolateManager.js
-front_end/sdk/HeapProfilerModel.js
-front_end/sdk/HARLog.js
-front_end/sdk/FilmStripModel.js
-front_end/sdk/EmulationModel.js
-front_end/sdk/DOMModel.js
-front_end/sdk/DOMDebuggerModel.js
-front_end/sdk/DebuggerModel.js
-front_end/sdk/CSSStyleSheetHeader.js
-front_end/sdk/CSSStyleDeclaration.js
-front_end/sdk/CSSRule.js
-front_end/sdk/CSSProperty.js
-front_end/sdk/CSSModel.js
-front_end/sdk/CSSMetadata.js
-front_end/sdk/CSSMedia.js
-front_end/sdk/CSSMatchedStyles.js
-front_end/sdk/CPUProfilerModel.js
-front_end/sdk/CPUProfileDataModel.js
-front_end/sdk/CookieParser.js
-front_end/sdk/CookieModel.js
-front_end/sdk/CompilerSourceMappingContentProvider.js
-front_end/sdk/ConsoleModel.js
-front_end/sdk/Connections.js
-front_end/sdk/ChildTargetManager.js
-front_end/protocol/protocol.js
-front_end/protocol/NodeURL.js
-front_end/protocol/InspectorBackend.js
-front_end/host/host.js
-front_end/host/UserMetrics.js
-front_end/host/ResourceLoader.js
-front_end/host/Platform.js
-front_end/host/InspectorFrontendHost.js
-front_end/host/InspectorFrontendHostAPI.js
-front_end/dom_extension/DOMExtension.js
-front_end/dom_extension/dom_extension.js
-front_end/root.js
-front_end/Runtime.js
-front_end/platform/utilities.js
-front_end/platform/platform.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ZoomManager.js
-front_end/ui/XWidget.js
-front_end/ui/XLink.js
-front_end/ui/XElement.js
-front_end/ui/Widget.js
-front_end/ui/View.js
-front_end/ui/ViewManager.js
-front_end/ui/UIUtils.js
-front_end/ui/ui.js
-front_end/ui/Treeoutline.js
-front_end/ui/Tooltip.js
-front_end/ui/Toolbar.js
-front_end/ui/ThrottledWidget.js
-front_end/ui/TextPrompt.js
-front_end/ui/TextEditor.js
-front_end/ui/TargetCrashedScreen.js
-front_end/ui/TabbedPane.js
-front_end/ui/SyntaxHighlighter.js
-front_end/ui/SuggestBox.js
-front_end/ui/SplitWidget.js
-front_end/ui/SoftDropDown.js
-front_end/ui/SoftContextMenu.js
-front_end/ui/ShortcutsScreen.js
-front_end/ui/ShortcutRegistry.js
-front_end/ui/SettingsUI.js
-front_end/ui/SegmentedButton.js
-front_end/ui/SearchableView.js
-front_end/ui/RootView.js
-front_end/ui/ResizerWidget.js
-front_end/ui/ReportView.js
-front_end/ui/RemoteDebuggingTerminatedScreen.js
-front_end/ui/ProgressIndicator.js
-front_end/ui/PopoverHelper.js
-front_end/ui/Panel.js
-front_end/ui/ListWidget.js
-front_end/ui/ListModel.js
-front_end/ui/ListControl.js
-front_end/ui/KeyboardShortcut.js
-front_end/ui/InspectorView.js
-front_end/ui/InplaceEditor.js
-front_end/ui/Infobar.js
-front_end/ui/Icon.js
-front_end/ui/HistoryInput.js
-front_end/ui/GlassPane.js
-front_end/ui/Geometry.js
-front_end/ui/Fragment.js
-front_end/ui/ForwardedInputEventHandler.js
-front_end/ui/FilterSuggestionBuilder.js
-front_end/ui/FilterBar.js
-front_end/ui/EmptyWidget.js
-front_end/ui/DropTarget.js
-front_end/ui/Dialog.js
-front_end/ui/ContextMenu.js
-front_end/ui/Context.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ActionRegistry.js
-front_end/ui/Action.js
-front_end/ui/ActionDelegate.js
-front_end/ui/ContextFlavorListener.js
-front_end/root.js
-front_end/common/common.js
-front_end/common/common-legacy.js
-front_end/common/App.js
-front_end/common/AppProvider.js
-front_end/common/CharacterIdMap.js
-front_end/common/Color.js
-front_end/common/ContentProvider.js
-front_end/common/EventTarget.js
-front_end/common/JavaScriptMetaData.js
-front_end/common/Linkifier.js
-front_end/common/Object.js
-front_end/common/Console.js
-front_end/common/ParsedURL.js
-front_end/common/Progress.js
-front_end/common/QueryParamHandler.js
-front_end/common/ResourceType.js
-front_end/common/Revealer.js
-front_end/common/Runnable.js
-front_end/common/SegmentedRange.js
-front_end/common/Settings.js
-front_end/common/StaticContentProvider.js
-front_end/common/StringOutputStream.js
-front_end/common/TextDictionary.js
-front_end/common/Throttler.js
-front_end/common/Trie.js
-front_end/common/UIString.js
-front_end/common/Worker.js
diff --git a/src/cobalt/demos/content/transparent-animated-webp-demo/index.html b/src/cobalt/demos/content/transparent-animated-webp-demo/index.html
index 62d21d9..e3fda4a 100644
--- a/src/cobalt/demos/content/transparent-animated-webp-demo/index.html
+++ b/src/cobalt/demos/content/transparent-animated-webp-demo/index.html
@@ -7,43 +7,45 @@
  | frames.
  -->
 <html>
+
 <head>
-<style>
-body {
-  background-color: white;
-}
+  <style>
+    body {
+      background-color: white;
+    }
 
-.layer {
-  position: absolute;
-  left: 0px;
-  top: 0px;
-}
+    .layer {
+      position: absolute;
+      left: 0px;
+      top: 0px;
+    }
 
-@keyframes background-anim {
-  from {
-    background-color: green;
-  }
-  to {
-    background-color: blue;
-  }
-}
+    @keyframes background-anim {
+      from {
+        background-color: green;
+      }
 
-.background {
-  position: absolute;
-  left: 0px;
-  top: 0px;
-  width:100%;
-  height:100%;
-  background-color: green;
-  animation: background-anim 5s alternate-reverse infinite ease-in-out;
-}
+      to {
+        background-color: blue;
+      }
+    }
 
-.image {
-  width: 300px;
-  height: 300px;
-  background-size: contain;
-}
-</style>
+    .background {
+      position: absolute;
+      left: 0px;
+      top: 0px;
+      width: 100%;
+      height: 100%;
+      background-color: green;
+      animation: background-anim 5s alternate-reverse infinite ease-in-out;
+    }
+
+    .image {
+      width: 300px;
+      height: 300px;
+      background-size: contain;
+    }
+  </style>
 </head>
 
 <body>
@@ -52,15 +54,17 @@
   <div class="layer">
     <!-- Image that clears each frame by overwriting the entire frame with a
          new image that has blending disabled -->
-    <div class="image"
-         style="background-image: url(bottleflip_loader.webp);">
+    <div class="image" style="background-image: url(bottleflip_loader.webp)">
     </div>
     <!-- Image that disposes the previous frame's rectangle to the background
          color (which contains alpha) after it finishes, requiring that the
          background color fill be done with no blending. -->
-    <div class="image"
-         style="background-image: url(webp-animated-semitransparent4.webp);">
+    <div class="image" style="background-image: url(webp-animated-semitransparent4.webp);">
+    </div>
+    <!-- Background color of image should be ignored, use canvas color instead-->
+    <div class="image" style="background-image: url(loading-spinner-opaque.webp)">
     </div>
   </div>
 </body>
-</html>
+
+</html>
\ No newline at end of file
diff --git a/src/cobalt/demos/content/transparent-animated-webp-demo/loading-spinner-opaque.webp b/src/cobalt/demos/content/transparent-animated-webp-demo/loading-spinner-opaque.webp
new file mode 100644
index 0000000..6cee3dd
--- /dev/null
+++ b/src/cobalt/demos/content/transparent-animated-webp-demo/loading-spinner-opaque.webp
Binary files differ
diff --git a/src/cobalt/demos/content/user-agent-client-hints-demo/user-agent-client-hints-demo.html b/src/cobalt/demos/content/user-agent-client-hints-demo/user-agent-client-hints-demo.html
new file mode 100644
index 0000000..d8cf908
--- /dev/null
+++ b/src/cobalt/demos/content/user-agent-client-hints-demo/user-agent-client-hints-demo.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      body {
+        color: white;
+      }
+      .title {
+        font-size: 24px;
+      }
+      .subtitle {
+        font-size: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="title">User-Agent Client Hints Demo</div>
+    <div id="brands" class="subtitle">Brands</div>
+    <div id="mobile" class="subtitle">Mobile indicator</div>
+    <div id="full" class="subtitle">Full User-Agent Data</div>
+
+    <script type="text/javascript">
+      // Enable User-Agent Client Hints API
+      h5vcc.settings.set("NavigatorUAData", 1);
+
+      if (navigator.userAgentData) {
+        var brands_result = document.createElement("div");
+        brands_result.innerHTML = JSON.stringify(navigator.userAgentData.brands, null, " ");
+        brands_result.style.fontSize = "16px";
+        var brands_element = document.getElementById("brands");
+        brands_element.appendChild(brands_result);
+
+        var mobile_result = document.createElement("div");
+        mobile_result.innerHTML = navigator.userAgentData.mobile;
+        mobile_result.style.fontSize = "16px";
+        var mobile_element = document.getElementById("mobile");
+        mobile_element.appendChild(mobile_result);
+
+        navigator.userAgentData.getHighEntropyValues(
+          ["architecture", "bitness", "model", "platformVersion",
+           "uaFullVersion", "cobaltBuildNumber", "cobaltBuildConfiguration",
+           "jsEngineVersion", "rasterizer", "evergreenVersion",
+           "starboardVersion", "originalDesignManufacturer",
+           "deviceType", "chipset", "modelYear", "deviceBrand",
+           "connectionType", "aux"])
+          .then(ua => {
+            // Cobalt returns a CobaltUADataValuesInterface object instead of a
+            // dictionary as dictionary promises are currently not supported.
+            // Thus we must reconstruct the dictionary from the interface object
+            // returned from getHighEntropyValues().
+            var full_JSON = new Object();
+            full_JSON.architecture = ua.architecture;
+            full_JSON.bitness = ua.bitness;
+            full_JSON.model = ua.model;
+            full_JSON.platformVersion = ua.platformVersion;
+            full_JSON.uaFullVersion = ua.uaFullVersion;
+            full_JSON.cobaltBuildNumber = ua.cobaltBuildNumber;
+            full_JSON.cobaltBuildConfiguration = ua.cobaltBuildConfiguration;
+            full_JSON.jsEngineVersion = ua.jsEngineVersion;
+            full_JSON.rasterizer = ua.rasterizer;
+            full_JSON.evergreenVersion = ua.evergreenVersion;
+            full_JSON.starboardVersion = ua.starboardVersion;
+            full_JSON.originalDesignManufacturer = ua.originalDesignManufacturer;
+            full_JSON.deviceType = ua.deviceType;
+            full_JSON.chipset = ua.chipset;
+            full_JSON.modelYear = ua.modelYear;
+            full_JSON.deviceBrand = ua.deviceBrand;
+            full_JSON.connectionType = ua.connectionType;
+            full_JSON.aux = ua.aux;
+
+            var full_result = document.createElement("div");
+            full_result.innerHTML = JSON.stringify(full_JSON, null, " ");
+            full_result.style.fontSize = "16px";
+            var full_element = document.getElementById("full");
+            full_element.appendChild(full_result);
+          });
+      } else {
+        console.log("User-Agent Client Hints API not enabled");
+      }
+    </script>
+  </body>
+</html>
diff --git a/src/cobalt/doc/performance_tuning.md b/src/cobalt/doc/performance_tuning.md
index 728ab56..f0a91ad 100644
--- a/src/cobalt/doc/performance_tuning.md
+++ b/src/cobalt/doc/performance_tuning.md
@@ -30,34 +30,6 @@
 **Tags:** *framerate, startup, browse-to-watch, cpu memory, input latency.*
 
 
-### Switch JavaScript Engine to V8
-
-Cobalt supports both SpiderMonkey and V8 as JavaScript engines.  SpiderMonkey
-is the default JavaScript engine since it is the most compatible in that it
-does not require your platform to support Just-In-Time (JIT) compiling.
-However, if your platform supports it, we strongly recommend that you use
-V8, as it has been shown to provide 20-50% speed improvements on JavaScript
-execution across the board.  Note however that V8 has also been found to
-consume around 10MB more memory than SpiderMonkey.
-
-To enable V8, you must modify the `GetVariables()` method in your
-`gyp_configuration.py` file and ensure that the variables dictionary that is
-returned contains the following key/value pair:
-
-```
-{
-  'javascript_engine': 'v8',
-}
-```
-
-Additionally, you must implement the `CobaltExtensionConfigurationApi` such
-that the `CobaltEnableJit()` method returns `true`.
-
-Note also that use of V8 requires Starboard version 10 or higher.
-
-**Tags:** *startup, browse-to-watch, cpu memory, input latency.*
-
-
 ### Framerate throttling
 
 If you're willing to accept a lower framerate, there is potential that
diff --git a/src/cobalt/dom/audio_track.h b/src/cobalt/dom/audio_track.h
index 361cd19..b3869e6 100644
--- a/src/cobalt/dom/audio_track.h
+++ b/src/cobalt/dom/audio_track.h
@@ -60,13 +60,13 @@
   //
   static bool IsValidKind(const char* kind) {
     // https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-audiotrack-audiotrackkind
-    return SbStringCompareAll(kind, "alternative") == 0 ||
-           SbStringCompareAll(kind, "descriptions") == 0 ||
-           SbStringCompareAll(kind, "main") == 0 ||
-           SbStringCompareAll(kind, "main-desc") == 0 ||
-           SbStringCompareAll(kind, "translation") == 0 ||
-           SbStringCompareAll(kind, "commentary") == 0 ||
-           SbStringGetLength(kind) == 0;
+    return strcmp(kind, "alternative") == 0 ||
+           strcmp(kind, "descriptions") == 0 ||
+           strcmp(kind, "main") == 0 ||
+           strcmp(kind, "main-desc") == 0 ||
+           strcmp(kind, "translation") == 0 ||
+           strcmp(kind, "commentary") == 0 ||
+           strlen(kind) == 0;
   }
 
   DEFINE_WRAPPABLE_TYPE(AudioTrack);
diff --git a/src/cobalt/dom/blob_test.cc b/src/cobalt/dom/blob_test.cc
index 41f33f9..eabba0b 100644
--- a/src/cobalt/dom/blob_test.cc
+++ b/src/cobalt/dom/blob_test.cc
@@ -47,7 +47,7 @@
   script::Handle<script::DataView> data_view = script::DataView::New(
       global_environment, array_buffer, 0, array_buffer->ByteLength());
   uint8 test_data[] = {0x06, 0x07, 0x00, 0x7B, 0xCD};
-  SbMemoryCopy(data_view->RawData(), test_data, 5);
+  memcpy(data_view->RawData(), test_data, 5);
   scoped_refptr<Blob> blob_with_buffer =
       new Blob(environment_settings, array_buffer);
 
@@ -101,7 +101,7 @@
       global_environment, array_buffer, 0, array_buffer->ByteLength());
 
   uint8 test_data[2] = {0x06, 0x07};
-  SbMemoryCopy(data_view->RawData(), test_data, 2);
+  memcpy(data_view->RawData(), test_data, 2);
 
   scoped_refptr<Blob> blob_with_buffer =
       new Blob(environment_settings, array_buffer);
diff --git a/src/cobalt/dom/captions/system_caption_settings.cc b/src/cobalt/dom/captions/system_caption_settings.cc
index 3fcc8d0..3a447f7 100644
--- a/src/cobalt/dom/captions/system_caption_settings.cc
+++ b/src/cobalt/dom/captions/system_caption_settings.cc
@@ -184,7 +184,7 @@
 base::Optional<std::string> SystemCaptionSettings::background_color() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -208,7 +208,7 @@
 CaptionState SystemCaptionSettings::background_color_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.background_color_state);
@@ -223,7 +223,7 @@
 base::Optional<std::string> SystemCaptionSettings::background_opacity() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -247,7 +247,7 @@
 CaptionState SystemCaptionSettings::background_opacity_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.background_opacity_state);
@@ -262,7 +262,7 @@
 base::Optional<std::string> SystemCaptionSettings::character_edge_style() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -288,7 +288,7 @@
 CaptionState SystemCaptionSettings::character_edge_style_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.character_edge_style_state);
@@ -303,7 +303,7 @@
 base::Optional<std::string> SystemCaptionSettings::font_color() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -327,7 +327,7 @@
 CaptionState SystemCaptionSettings::font_color_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.font_color_state);
@@ -342,7 +342,7 @@
 base::Optional<std::string> SystemCaptionSettings::font_family() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -366,7 +366,7 @@
 CaptionState SystemCaptionSettings::font_family_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.font_family_state);
@@ -381,7 +381,7 @@
 base::Optional<std::string> SystemCaptionSettings::font_opacity() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -405,7 +405,7 @@
 CaptionState SystemCaptionSettings::font_opacity_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.font_opacity_state);
@@ -420,7 +420,7 @@
 base::Optional<std::string> SystemCaptionSettings::font_size() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -445,7 +445,7 @@
 CaptionState SystemCaptionSettings::font_size_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.font_size_state);
@@ -460,7 +460,7 @@
 base::Optional<std::string> SystemCaptionSettings::window_color() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -484,7 +484,7 @@
 CaptionState SystemCaptionSettings::window_color_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.window_color_state);
@@ -499,7 +499,7 @@
 base::Optional<std::string> SystemCaptionSettings::window_opacity() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   if (!success) {
@@ -523,7 +523,7 @@
 CaptionState SystemCaptionSettings::window_opacity_state() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   if (success) {
     return ToCobaltCaptionState(caption_settings.window_opacity_state);
@@ -538,7 +538,7 @@
 bool SystemCaptionSettings::is_enabled() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
   DCHECK(supports_is_enabled());
 
@@ -561,7 +561,7 @@
 bool SystemCaptionSettings::supports_is_enabled() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   return (success) ? caption_settings.supports_is_enabled : false;
@@ -574,7 +574,7 @@
 bool SystemCaptionSettings::supports_set_enabled() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   return (success) ? caption_settings.supports_set_enabled : false;
@@ -587,7 +587,7 @@
 bool SystemCaptionSettings::supports_override() {
 #if SB_API_VERSION >= 12 || SB_HAS(CAPTIONS)
   SbAccessibilityCaptionSettings caption_settings;
-  SbMemorySet(&caption_settings, 0, sizeof(caption_settings));
+  memset(&caption_settings, 0, sizeof(caption_settings));
   bool success = SbAccessibilityGetCaptionSettings(&caption_settings);
 
   return (success) ? caption_settings.supports_override : false;
diff --git a/src/cobalt/dom/cobalt_ua_data_values.idl b/src/cobalt/dom/cobalt_ua_data_values.idl
index 62c3b30..000b238 100644
--- a/src/cobalt/dom/cobalt_ua_data_values.idl
+++ b/src/cobalt/dom/cobalt_ua_data_values.idl
@@ -21,6 +21,8 @@
   DOMString rasterizer;
   DOMString evergreenVersion;
   DOMString starboardVersion;
+  DOMString originalDesignManufacturer;
+  DOMString deviceType;
   DOMString chipset;
   DOMString modelYear;
   DOMString deviceBrand;
diff --git a/src/cobalt/dom/cobalt_ua_data_values_interface.cc b/src/cobalt/dom/cobalt_ua_data_values_interface.cc
new file mode 100644
index 0000000..a688cf8
--- /dev/null
+++ b/src/cobalt/dom/cobalt_ua_data_values_interface.cc
@@ -0,0 +1,91 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cobalt/dom/cobalt_ua_data_values_interface.h"
+
+namespace cobalt {
+namespace dom {
+
+CobaltUADataValuesInterface::CobaltUADataValuesInterface(
+    const CobaltUADataValues& init_dict) {
+  // In many cases, |init_dict| will not have all its fields initialized, only
+  // the ones specified when calling NavigatorUAData::getHighEntropyValues().
+  // Thus, we first must check whether the fields have been initialized.
+  if (init_dict.has_brands()) {
+    brands_ = init_dict.brands();
+  }
+  if (init_dict.has_mobile()) {
+    mobile_ = init_dict.mobile();
+  }
+  if (init_dict.has_platform()) {
+    platform_ = init_dict.platform();
+  }
+  if (init_dict.has_architecture()) {
+    architecture_ = init_dict.architecture();
+  }
+  if (init_dict.has_bitness()) {
+    bitness_ = init_dict.bitness();
+  }
+  if (init_dict.has_model()) {
+    model_ = init_dict.model();
+  }
+  if (init_dict.has_platform()) {
+    platform_ = init_dict.platform();
+  }
+  if (init_dict.has_ua_full_version()) {
+    ua_full_version_ = init_dict.ua_full_version();
+  }
+  if (init_dict.has_cobalt_build_number()) {
+    cobalt_build_number_ = init_dict.cobalt_build_number();
+  }
+  if (init_dict.has_cobalt_build_configuration()) {
+    cobalt_build_configuration_ = init_dict.cobalt_build_configuration();
+  }
+  if (init_dict.has_js_engine_version()) {
+    js_engine_version_ = init_dict.js_engine_version();
+  }
+  if (init_dict.has_rasterizer()) {
+    rasterizer_ = init_dict.rasterizer();
+  }
+  if (init_dict.has_evergreen_version()) {
+    evergreen_version_ = init_dict.evergreen_version();
+  }
+  if (init_dict.has_starboard_version()) {
+    starboard_version_ = init_dict.starboard_version();
+  }
+  if (init_dict.has_original_design_manufacturer()) {
+    original_design_manufacturer_ = init_dict.original_design_manufacturer();
+  }
+  if (init_dict.has_device_type()) {
+    device_type_ = init_dict.device_type();
+  }
+  if (init_dict.has_chipset()) {
+    chipset_ = init_dict.chipset();
+  }
+  if (init_dict.has_model_year()) {
+    model_year_ = init_dict.model_year();
+  }
+  if (init_dict.has_device_brand()) {
+    device_brand_ = init_dict.device_brand();
+  }
+  if (init_dict.has_connection_type()) {
+    connection_type_ = init_dict.connection_type();
+  }
+  if (init_dict.has_aux()) {
+    aux_ = init_dict.aux();
+  }
+}
+
+}  // namespace dom
+}  // namespace cobalt
diff --git a/src/cobalt/dom/cobalt_ua_data_values_interface.h b/src/cobalt/dom/cobalt_ua_data_values_interface.h
new file mode 100644
index 0000000..e3ef570
--- /dev/null
+++ b/src/cobalt/dom/cobalt_ua_data_values_interface.h
@@ -0,0 +1,91 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_COBALT_UA_DATA_VALUES_INTERFACE_H_
+#define COBALT_DOM_COBALT_UA_DATA_VALUES_INTERFACE_H_
+
+#include <string>
+
+#include "cobalt/dom/cobalt_ua_data_values.h"
+#include "cobalt/script/wrappable.h"
+
+namespace cobalt {
+namespace dom {
+
+class CobaltUADataValuesInterface : public script::Wrappable {
+ public:
+  explicit CobaltUADataValuesInterface(const CobaltUADataValues& init_dict);
+
+  script::Sequence<NavigatorUABrandVersion> brands() const { return brands_; }
+  bool mobile() const { return mobile_; }
+  const std::string& platform() const { return platform_; }
+  const std::string& architecture() const { return architecture_; }
+  const std::string& bitness() const { return bitness_; }
+  const std::string& model() const { return model_; }
+  const std::string& platform_version() const { return platform_version_; }
+  const std::string& ua_full_version() const { return ua_full_version_; }
+  const std::string& cobalt_build_number() const {
+    return cobalt_build_number_;
+  }
+  const std::string& cobalt_build_configuration() const {
+    return cobalt_build_configuration_;
+  }
+  const std::string& js_engine_version() const { return js_engine_version_; }
+  const std::string& rasterizer() const { return rasterizer_; }
+  const std::string& evergreen_version() const { return evergreen_version_; }
+  const std::string& starboard_version() const { return starboard_version_; }
+  const std::string& original_design_manufacturer() const {
+    return original_design_manufacturer_;
+  }
+  const std::string& device_type() const { return device_type_; }
+  const std::string& chipset() const { return chipset_; }
+  const std::string& model_year() const { return model_year_; }
+  const std::string& device_brand() const { return device_brand_; }
+  const std::string& connection_type() const { return connection_type_; }
+  const std::string& aux() const { return aux_; }
+
+  DEFINE_WRAPPABLE_TYPE(CobaltUADataValuesInterface);
+
+ private:
+  ~CobaltUADataValuesInterface() override {}
+
+  script::Sequence<NavigatorUABrandVersion> brands_;
+  bool mobile_;
+  std::string platform_;
+  std::string architecture_;
+  std::string bitness_;
+  std::string model_;
+  std::string platform_version_;
+  std::string ua_full_version_;
+  std::string cobalt_build_number_;
+  std::string cobalt_build_configuration_;
+  std::string js_engine_version_;
+  std::string rasterizer_;
+  std::string evergreen_version_;
+  std::string starboard_version_;
+  std::string original_design_manufacturer_;
+  std::string device_type_;
+  std::string chipset_;
+  std::string model_year_;
+  std::string device_brand_;
+  std::string connection_type_;
+  std::string aux_;
+
+  DISALLOW_COPY_AND_ASSIGN(CobaltUADataValuesInterface);
+};
+
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_COBALT_UA_DATA_VALUES_INTERFACE_H_
diff --git a/src/cobalt/dom/cobalt_ua_data_values_interface.idl b/src/cobalt/dom/cobalt_ua_data_values_interface.idl
new file mode 100644
index 0000000..179ac91
--- /dev/null
+++ b/src/cobalt/dom/cobalt_ua_data_values_interface.idl
@@ -0,0 +1,41 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Custom, not in spec. Interface wrapper for CobaltUADataValues to make
+// compatible with Promises implementation in Cobalt.
+
+[Constructor(CobaltUADataValues cobaltUADataValues)]
+interface CobaltUADataValuesInterface {
+  readonly attribute sequence<NavigatorUABrandVersion> brands;
+  readonly attribute boolean mobile;
+  readonly attribute DOMString platform;
+  readonly attribute DOMString architecture;
+  readonly attribute DOMString bitness;
+  readonly attribute DOMString model;
+  readonly attribute DOMString platformVersion;
+  readonly attribute DOMString uaFullVersion;
+  readonly attribute DOMString cobaltBuildNumber;
+  readonly attribute DOMString cobaltBuildConfiguration;
+  readonly attribute DOMString jsEngineVersion;
+  readonly attribute DOMString rasterizer;
+  readonly attribute DOMString evergreenVersion;
+  readonly attribute DOMString starboardVersion;
+  readonly attribute DOMString originalDesignManufacturer;
+  readonly attribute DOMString deviceType;
+  readonly attribute DOMString chipset;
+  readonly attribute DOMString modelYear;
+  readonly attribute DOMString deviceBrand;
+  readonly attribute DOMString connectionType;
+  readonly attribute DOMString aux;
+};
diff --git a/src/cobalt/dom/custom_event_test.cc b/src/cobalt/dom/custom_event_test.cc
index 083c08f..4a3c1e7 100644
--- a/src/cobalt/dom/custom_event_test.cc
+++ b/src/cobalt/dom/custom_event_test.cc
@@ -75,7 +75,7 @@
         base::kApplicationStateStarted, css_parser_.get(), dom_parser_.get(),
         fetcher_factory_.get(), loader_factory_.get(), NULL, NULL, NULL, NULL,
         NULL, NULL, &local_storage_database_, NULL, NULL, NULL, NULL,
-        global_environment_->script_value_factory(), NULL, NULL, url_, "",
+        global_environment_->script_value_factory(), NULL, NULL, url_, "", NULL,
         "en-US", "en", base::Callback<void(const GURL&)>(),
         base::Bind(&MockErrorCallback::Run,
                    base::Unretained(&mock_error_callback_)),
diff --git a/src/cobalt/dom/dom.gyp b/src/cobalt/dom/dom.gyp
index 93b5c44..4039e2c 100644
--- a/src/cobalt/dom/dom.gyp
+++ b/src/cobalt/dom/dom.gyp
@@ -53,6 +53,8 @@
         'cdata_section.h',
         'character_data.cc',
         'character_data.h',
+        'cobalt_ua_data_values_interface.cc',
+        'cobalt_ua_data_values_interface.h',
         'comment.cc',
         'comment.h',
         'crypto.cc',
@@ -236,6 +238,7 @@
         'named_node_map.h',
         'navigator.cc',
         'navigator.h',
+        'navigator_ua_data.cc',
         'navigator_ua_data.h',
         'node.cc',
         'node.h',
@@ -259,6 +262,12 @@
         'performance_entry.h',
         'performance_entry_list_impl.cc',
         'performance_entry_list_impl.h',
+        'performance_lifecycle_timing.cc',
+        'performance_lifecycle_timing.h',
+        'performance_mark.cc',
+        'performance_mark.h',
+        'performance_measure.cc',
+        'performance_measure.h',
         'performance_observer.cc',
         'performance_observer.h',
         'performance_observer_entry_list.cc',
@@ -324,6 +333,7 @@
         'url_registry.h',
         'url_utils.cc',
         'url_utils.h',
+        'user_agent_platform_info.h',
         'video_track.h',
         'video_track_list.h',
         'wheel_event.cc',
diff --git a/src/cobalt/dom/eme/media_key_session.h b/src/cobalt/dom/eme/media_key_session.h
index e95c7de..f9886b5 100644
--- a/src/cobalt/dom/eme/media_key_session.h
+++ b/src/cobalt/dom/eme/media_key_session.h
@@ -102,9 +102,6 @@
   bool callable_;
   scoped_refptr<MediaKeyStatusMap> key_status_map_;
 
-  // TODO: Remove |closed_callback_| and change call sites to use closed()
-  //       promise instead, once Cobalt switches to native SpiderMonkey
-  //       promises.
   const ClosedCallback closed_callback_;
   const VoidPromiseValue::Reference closed_promise_reference_;
 
diff --git a/src/cobalt/dom/error_event_test.cc b/src/cobalt/dom/error_event_test.cc
index 7f431a7..8cbfdec 100644
--- a/src/cobalt/dom/error_event_test.cc
+++ b/src/cobalt/dom/error_event_test.cc
@@ -77,7 +77,7 @@
         css_parser_.get(), dom_parser_.get(), fetcher_factory_.get(),
         loader_factory_.get(), NULL, NULL, NULL, NULL, NULL, NULL,
         &local_storage_database_, NULL, NULL, NULL, NULL,
-        global_environment_->script_value_factory(), NULL, NULL, url_, "",
+        global_environment_->script_value_factory(), NULL, NULL, url_, "", NULL,
         "en-US", "en", base::Callback<void(const GURL&)>(),
         base::Bind(&MockLoadCompleteCallback::Run,
                    base::Unretained(&mock_load_complete_callback_)),
diff --git a/src/cobalt/dom/html_element_factory.cc b/src/cobalt/dom/html_element_factory.cc
index a753273..ad47e8d 100644
--- a/src/cobalt/dom/html_element_factory.cc
+++ b/src/cobalt/dom/html_element_factory.cc
@@ -67,26 +67,26 @@
 bool IsBlacklistedTag(const char* tag, int length) {
   switch (length) {
     case 9:
-      if (SbStringCompareAll(tag, "font-face") == 0) {
+      if (strcmp(tag, "font-face") == 0) {
         return true;
       }
       break;
     case 13:
-      if (SbStringCompareAll(tag, "font-face-src") == 0 ||
-          SbStringCompareAll(tag, "missing-glyph") == 0 ||
-          SbStringCompareAll(tag, "color-profile") == 0 ||
-          SbStringCompareAll(tag, "font-face-uri") == 0) {
+      if (strcmp(tag, "font-face-src") == 0 ||
+          strcmp(tag, "missing-glyph") == 0 ||
+          strcmp(tag, "color-profile") == 0 ||
+          strcmp(tag, "font-face-uri") == 0) {
         return true;
       }
       break;
     case 14:
-      if (SbStringCompareAll(tag, "font-face-name") == 0 ||
-          SbStringCompareAll(tag, "annotation-xml") == 0) {
+      if (strcmp(tag, "font-face-name") == 0 ||
+          strcmp(tag, "annotation-xml") == 0) {
         return true;
       }
       break;
     case 16:
-      if (SbStringCompareAll(tag, "font-face-format") == 0) {
+      if (strcmp(tag, "font-face-format") == 0) {
         return true;
       }
       break;
diff --git a/src/cobalt/dom/html_link_element.cc b/src/cobalt/dom/html_link_element.cc
index 7181f4d..3e398c7 100644
--- a/src/cobalt/dom/html_link_element.cc
+++ b/src/cobalt/dom/html_link_element.cc
@@ -45,7 +45,7 @@
   bool is_valid_format = true;
   while (tokenizer.GetNext()) {
     std::string token = tokenizer.token();
-    if (SbStringCompareAll(token.c_str(), "splashscreen") == 0) {
+    if (strcmp(token.c_str(), "splashscreen") == 0) {
       is_valid_format = true;
     } else {
       for (char const& c : token) {
@@ -279,6 +279,9 @@
     // complete.
     node_document()->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
   }
+
+  // GetLoadTimingInfo and create resource timing before loader released.
+  GetLoadTimingInfoAndCreateResourceTiming();
 }
 
 void HTMLLinkElement::OnSplashscreenLoaded(Document* document,
@@ -313,8 +316,6 @@
 void HTMLLinkElement::ReleaseLoader() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(loader_);
-  // GetLoadTimingInfo from loader before reset.
-  GetLoadTimingInfoAndCreateResourceTiming();
   loader_.reset();
 }
 
@@ -327,8 +328,10 @@
 
 void HTMLLinkElement::GetLoadTimingInfoAndCreateResourceTiming() {
   if (html_element_context()->performance() == nullptr) return;
-  html_element_context()->performance()->CreatePerformanceResourceTiming(
-      loader_->get_load_timing_info(), kTagName, absolute_url_.spec());
+  if (loader_) {
+    html_element_context()->performance()->CreatePerformanceResourceTiming(
+        loader_->get_load_timing_info(), kTagName, absolute_url_.spec());
+  }
 }
 
 }  // namespace dom
diff --git a/src/cobalt/dom/html_script_element.cc b/src/cobalt/dom/html_script_element.cc
index 7a536f7..ad9386e 100644
--- a/src/cobalt/dom/html_script_element.cc
+++ b/src/cobalt/dom/html_script_element.cc
@@ -596,6 +596,9 @@
   // once the resource has been fetched (defined above) has been run.
   document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
 
+  // GetLoadTimingInfo and create resource timing before loader released.
+  GetLoadTimingInfoAndCreateResourceTiming();
+
   // Post a task to release the loader.
   base::MessageLoop::current()->task_runner()->PostTask(
       FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this));
@@ -720,15 +723,15 @@
 void HTMLScriptElement::ReleaseLoader() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(loader_);
-  // GetLoadTimingInfo from loader before reset.
-  GetLoadTimingInfoAndCreateResourceTiming();
   loader_.reset();
 }
 
 void HTMLScriptElement::GetLoadTimingInfoAndCreateResourceTiming() {
   if (html_element_context()->performance() == nullptr) return;
-  html_element_context()->performance()->CreatePerformanceResourceTiming(
+  if (loader_) {
+    html_element_context()->performance()->CreatePerformanceResourceTiming(
       loader_->get_load_timing_info(), kTagName, url_.spec());
+  }
 }
 
 }  // namespace dom
diff --git a/src/cobalt/dom/message_event.cc b/src/cobalt/dom/message_event.cc
index f7843aa..fa4359c 100644
--- a/src/cobalt/dom/message_event.cc
+++ b/src/cobalt/dom/message_event.cc
@@ -46,7 +46,7 @@
 MessageEvent::ResponseTypeCode MessageEvent::GetResponseTypeCode(
     base::StringPiece to_match) {
   for (std::size_t i = 0; i != arraysize(kResponseTypes); ++i) {
-    if (SbStringCompare(kResponseTypes[i], to_match.data(), to_match.size()) ==
+    if (strncmp(kResponseTypes[i], to_match.data(), to_match.size()) ==
         0) {
       return MessageEvent::ResponseTypeCode(i);
     }
diff --git a/src/cobalt/dom/navigator.cc b/src/cobalt/dom/navigator.cc
index f02ade8..55fbf20 100644
--- a/src/cobalt/dom/navigator.cc
+++ b/src/cobalt/dom/navigator.cc
@@ -145,10 +145,12 @@
 
 Navigator::Navigator(
     script::EnvironmentSettings* settings, const std::string& user_agent,
-    const std::string& language,
+    UserAgentPlatformInfo* platform_info, const std::string& language,
     scoped_refptr<cobalt::dom::captions::SystemCaptionSettings> captions,
     script::ScriptValueFactory* script_value_factory)
     : user_agent_(user_agent),
+      user_agent_data_(
+          new NavigatorUAData(platform_info, script_value_factory)),
       language_(language),
       mime_types_(new MimeTypeArray()),
       plugins_(new PluginArray()),
diff --git a/src/cobalt/dom/navigator.h b/src/cobalt/dom/navigator.h
index b679176..29e68cd 100644
--- a/src/cobalt/dom/navigator.h
+++ b/src/cobalt/dom/navigator.h
@@ -43,7 +43,7 @@
  public:
   Navigator(
       script::EnvironmentSettings* settings, const std::string& user_agent,
-      const std::string& language,
+      UserAgentPlatformInfo* platform_info, const std::string& language,
       scoped_refptr<cobalt::dom::captions::SystemCaptionSettings> captions,
       script::ScriptValueFactory* script_value_factory);
 
diff --git a/src/cobalt/dom/navigator.idl b/src/cobalt/dom/navigator.idl
index acbf4b8..6a21520 100644
--- a/src/cobalt/dom/navigator.idl
+++ b/src/cobalt/dom/navigator.idl
@@ -17,7 +17,6 @@
 interface Navigator {};
 
 Navigator implements NavigatorID;
-Navigator implements NavigatorUA;
 Navigator implements NavigatorLanguage;
 Navigator implements NavigatorPlugins;
 Navigator implements NavigatorStorageUtils;
diff --git a/src/cobalt/dom/navigator_licenses_test.cc b/src/cobalt/dom/navigator_licenses_test.cc
index cc55b6b..69030d1 100644
--- a/src/cobalt/dom/navigator_licenses_test.cc
+++ b/src/cobalt/dom/navigator_licenses_test.cc
@@ -23,7 +23,7 @@
 TEST(NavigatorLicensesTest, NonEmpty) {
   testing::StubEnvironmentSettings environment_settings;
   scoped_refptr<cobalt::dom::Navigator> navigator =
-      new cobalt::dom::Navigator(&environment_settings, std::string(),
+      new cobalt::dom::Navigator(&environment_settings, std::string(), NULL,
                                  std::string(), nullptr, nullptr);
 
   ASSERT_TRUE(navigator != nullptr);
diff --git a/src/cobalt/dom/navigator_ua.idl b/src/cobalt/dom/navigator_ua.idl
index 3f10c9d..74780fa 100644
--- a/src/cobalt/dom/navigator_ua.idl
+++ b/src/cobalt/dom/navigator_ua.idl
@@ -13,6 +13,11 @@
 // limitations under the License.
 
 // https://wicg.github.io/ua-client-hints/#navigatorua
+// Accessing this interface through JavaScript via "navigator.userAgentData" is
+// currently disabled by default; we inject the interface via H5vccSettings
+// per user request.
+// In the future, we can enable this interface by default by adding "Navigator
+// implements NavigatorUA" to navigator.idl
 
 [NoInterfaceObject]
 interface NavigatorUA {
diff --git a/src/cobalt/dom/navigator_ua_data.cc b/src/cobalt/dom/navigator_ua_data.cc
new file mode 100644
index 0000000..2d19869
--- /dev/null
+++ b/src/cobalt/dom/navigator_ua_data.cc
@@ -0,0 +1,160 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cobalt/dom/navigator_ua_data.h"
+
+#include "base/strings/stringprintf.h"
+
+namespace cobalt {
+namespace dom {
+
+NavigatorUAData::NavigatorUAData(
+    UserAgentPlatformInfo* platform_info,
+    script::ScriptValueFactory* script_value_factory)
+    : script_value_factory_(script_value_factory) {
+  if (platform_info == nullptr) {
+    SB_DLOG(WARNING)
+        << "No UserAgentPlatformInfo object passed to NavigatorUAData";
+    return;
+  }
+  NavigatorUABrandVersion cobalt_brand;
+  cobalt_brand.set_brand("Cobalt");
+  cobalt_brand.set_version(platform_info->cobalt_version());
+  brands_.push_back(cobalt_brand);
+
+  mobile_ = false;
+  platform_ = platform_info->os_name_and_version();
+
+  all_high_entropy_values_.set_brands(brands_);
+  all_high_entropy_values_.set_mobile(mobile_);
+  all_high_entropy_values_.set_platform(platform_);
+#if SB_API_VERSION >= 12
+  all_high_entropy_values_.set_architecture(SB_SABI_TARGET_ARCH);
+  all_high_entropy_values_.set_bitness(SB_SABI_WORD_SIZE);
+#endif
+  all_high_entropy_values_.set_model(platform_info->model().value_or(""));
+  all_high_entropy_values_.set_platform_version(
+      platform_info->firmware_version().value_or(""));
+  all_high_entropy_values_.set_ua_full_version(
+      base::StringPrintf("%s.%s-%s", platform_info->cobalt_version().c_str(),
+                         platform_info->cobalt_build_version_number().c_str(),
+                         platform_info->build_configuration().c_str()));
+  all_high_entropy_values_.set_cobalt_build_number(
+      platform_info->cobalt_build_version_number());
+  all_high_entropy_values_.set_cobalt_build_configuration(
+      platform_info->build_configuration());
+  all_high_entropy_values_.set_js_engine_version(
+      platform_info->javascript_engine_version());
+  all_high_entropy_values_.set_rasterizer(platform_info->rasterizer_type());
+  all_high_entropy_values_.set_evergreen_version(
+      platform_info->evergreen_version());
+  all_high_entropy_values_.set_starboard_version(
+      platform_info->starboard_version());
+  all_high_entropy_values_.set_original_design_manufacturer(
+      platform_info->original_design_manufacturer().value_or(""));
+  all_high_entropy_values_.set_device_type(platform_info->device_type_string());
+  all_high_entropy_values_.set_chipset(
+      platform_info->chipset_model_number().value_or(""));
+  all_high_entropy_values_.set_model_year(
+      platform_info->model_year().value_or(""));
+  all_high_entropy_values_.set_device_brand(
+      platform_info->brand().value_or(""));
+  all_high_entropy_values_.set_connection_type(
+      platform_info->connection_type_string());
+  all_high_entropy_values_.set_aux(platform_info->aux_field());
+
+  low_entropy_json_.set_brands(brands_);
+  low_entropy_json_.set_mobile(mobile_);
+  low_entropy_json_.set_platform(platform_);
+}
+
+script::Handle<NavigatorUAData::InterfacePromise>
+NavigatorUAData::GetHighEntropyValues(script::Sequence<std::string> hints) {
+  // https://wicg.github.io/ua-client-hints/#getHighEntropyValues
+  CobaltUADataValues select_high_entropy_values_;
+
+  // Set brands, mobile, and platform
+  select_high_entropy_values_.set_brands(all_high_entropy_values_.brands());
+  select_high_entropy_values_.set_mobile(all_high_entropy_values_.mobile());
+  select_high_entropy_values_.set_platform(all_high_entropy_values_.platform());
+
+  // Set other hints if specified
+  for (script::Sequence<std::string>::iterator it = hints.begin();
+       it != hints.end(); ++it) {
+    if ((*it).compare("architecture") == 0) {
+      select_high_entropy_values_.set_architecture(
+          all_high_entropy_values_.architecture());
+    } else if ((*it).compare("bitness") == 0) {
+      select_high_entropy_values_.set_bitness(
+          all_high_entropy_values_.bitness());
+    } else if ((*it).compare("model") == 0) {
+      select_high_entropy_values_.set_model(all_high_entropy_values_.model());
+    } else if ((*it).compare("platformVersion") == 0) {
+      select_high_entropy_values_.set_platform_version(
+          all_high_entropy_values_.platform_version());
+    } else if ((*it).compare("uaFullVersion") == 0) {
+      select_high_entropy_values_.set_ua_full_version(
+          all_high_entropy_values_.ua_full_version());
+    } else if ((*it).compare("cobaltBuildNumber") == 0) {
+      select_high_entropy_values_.set_cobalt_build_number(
+          all_high_entropy_values_.cobalt_build_number());
+    } else if ((*it).compare("cobaltBuildConfiguration") == 0) {
+      select_high_entropy_values_.set_cobalt_build_configuration(
+          all_high_entropy_values_.cobalt_build_configuration());
+    } else if ((*it).compare("jsEngineVersion") == 0) {
+      select_high_entropy_values_.set_js_engine_version(
+          all_high_entropy_values_.js_engine_version());
+    } else if ((*it).compare("rasterizer") == 0) {
+      select_high_entropy_values_.set_rasterizer(
+          all_high_entropy_values_.rasterizer());
+    } else if ((*it).compare("evergreenVersion") == 0) {
+      select_high_entropy_values_.set_evergreen_version(
+          all_high_entropy_values_.evergreen_version());
+    } else if ((*it).compare("starboardVersion") == 0) {
+      select_high_entropy_values_.set_starboard_version(
+          all_high_entropy_values_.starboard_version());
+    } else if ((*it).compare("originalDesignManufacturer") == 0) {
+      select_high_entropy_values_.set_original_design_manufacturer(
+          all_high_entropy_values_.original_design_manufacturer());
+    } else if ((*it).compare("deviceType") == 0) {
+      select_high_entropy_values_.set_device_type(
+          all_high_entropy_values_.device_type());
+    } else if ((*it).compare("chipset") == 0) {
+      select_high_entropy_values_.set_chipset(
+          all_high_entropy_values_.chipset());
+    } else if ((*it).compare("modelYear") == 0) {
+      select_high_entropy_values_.set_model_year(
+          all_high_entropy_values_.model_year());
+    } else if ((*it).compare("deviceBrand") == 0) {
+      select_high_entropy_values_.set_device_brand(
+          all_high_entropy_values_.device_brand());
+    } else if ((*it).compare("connectionType") == 0) {
+      select_high_entropy_values_.set_connection_type(
+          all_high_entropy_values_.connection_type());
+    } else if ((*it).compare("aux") == 0) {
+      select_high_entropy_values_.set_aux(all_high_entropy_values_.aux());
+    }
+  }
+
+  script::Handle<InterfacePromise> promise =
+      script_value_factory_->CreateInterfacePromise<
+          scoped_refptr<CobaltUADataValuesInterface>>();
+  scoped_refptr<CobaltUADataValuesInterface> promise_result(
+      new CobaltUADataValuesInterface(select_high_entropy_values_));
+  promise->Resolve(promise_result);
+  return promise;
+}
+
+}  // namespace dom
+}  // namespace cobalt
diff --git a/src/cobalt/dom/navigator_ua_data.h b/src/cobalt/dom/navigator_ua_data.h
index 1878093..8b2a7b5 100644
--- a/src/cobalt/dom/navigator_ua_data.h
+++ b/src/cobalt/dom/navigator_ua_data.h
@@ -17,10 +17,13 @@
 
 #include <string>
 
-#include "cobalt/dom/cobalt_ua_data_values.h"
+#include "cobalt/dom/cobalt_ua_data_values_interface.h"
 #include "cobalt/dom/navigator_ua_brand_version.h"
 #include "cobalt/dom/ua_low_entropy_json.h"
+#include "cobalt/dom/user_agent_platform_info.h"
 #include "cobalt/script/promise.h"
+#include "cobalt/script/script_value.h"
+#include "cobalt/script/script_value_factory.h"
 #include "cobalt/script/sequence.h"
 #include "cobalt/script/wrappable.h"
 
@@ -31,7 +34,10 @@
 // https://wicg.github.io/ua-client-hints/#navigatoruadata
 class NavigatorUAData : public script::Wrappable {
  public:
-  NavigatorUAData() {}
+  using InterfacePromise = script::Promise<scoped_refptr<script::Wrappable>>;
+
+  NavigatorUAData(UserAgentPlatformInfo* platform_info,
+                  script::ScriptValueFactory* script_value_factory);
 
   script::Sequence<NavigatorUABrandVersion> brands() const { return brands_; }
 
@@ -39,10 +45,8 @@
 
   std::string platform() const { return platform_; }
 
-  script::Handle<script::Promise<CobaltUADataValues>> GetHighEntropyValues(
-      script::Sequence<std::string> hints) {
-    return high_entropy_values_;
-  }
+  script::Handle<InterfacePromise> GetHighEntropyValues(
+      script::Sequence<std::string> hints);
 
   UALowEntropyJSON ToJSON() { return low_entropy_json_; }
 
@@ -54,8 +58,9 @@
   script::Sequence<NavigatorUABrandVersion> brands_;
   bool mobile_;
   std::string platform_;
-  script::Handle<script::Promise<CobaltUADataValues>> high_entropy_values_;
+  CobaltUADataValues all_high_entropy_values_;
   UALowEntropyJSON low_entropy_json_;
+  script::ScriptValueFactory* script_value_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(NavigatorUAData);
 };
diff --git a/src/cobalt/dom/navigator_ua_data.idl b/src/cobalt/dom/navigator_ua_data.idl
index 5d1bf3e..3eacfb5 100644
--- a/src/cobalt/dom/navigator_ua_data.idl
+++ b/src/cobalt/dom/navigator_ua_data.idl
@@ -20,6 +20,8 @@
   readonly attribute sequence<NavigatorUABrandVersion> brands;
   readonly attribute boolean mobile;
   readonly attribute DOMString platform;
-  Promise<CobaltUADataValues> getHighEntropyValues(sequence<DOMString> hints);
+  // TODO make this a Promise<CobaltUADataValues> when support for dictionary
+  // Promises becomes available in Cobalt
+  Promise<CobaltUADataValuesInterface> getHighEntropyValues(sequence<DOMString> hints);
   UALowEntropyJSON toJSON();
 };
diff --git a/src/cobalt/dom/on_screen_keyboard_test.cc b/src/cobalt/dom/on_screen_keyboard_test.cc
index 701c842..08760bb 100644
--- a/src/cobalt/dom/on_screen_keyboard_test.cc
+++ b/src/cobalt/dom/on_screen_keyboard_test.cc
@@ -212,7 +212,7 @@
             NULL, NULL, NULL,
             global_environment_
                 ->script_value_factory() /* script_value_factory */,
-            NULL, NULL, url_, "", "en-US", "en",
+            NULL, NULL, url_, "", NULL, "en-US", "en",
             base::Callback<void(const GURL&)>(),
             base::Bind(&MockErrorCallback::Run,
                        base::Unretained(&mock_error_callback_)),
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index 94a50bc..2428bc5 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -14,33 +14,109 @@
 
 #include "cobalt/dom/performance.h"
 
+#include <string>
+
 #include "base/time/time.h"
+#include "base/time/default_clock.h"
 #include "cobalt/browser/stack_size_constants.h"
+#include "cobalt/dom/dom_exception.h"
 #include "cobalt/dom/memory_info.h"
 #include "cobalt/dom/performance_entry.h"
+#include "cobalt/dom/performance_mark.h"
+#include "cobalt/dom/performance_measure.h"
 
 namespace cobalt {
 namespace dom {
 
+namespace {
+
+base::TimeDelta GetUnixAtZeroMonotonic(const base::Clock* clock,
+                                         const base::TickClock* tick_clock) {
+  base::TimeDelta unix_time_now = clock->Now() - base::Time::UnixEpoch();
+  base::TimeDelta time_since_origin = tick_clock->NowTicks().since_origin();
+  return unix_time_now - time_since_origin;
+}
+
+bool IsNamePerformanceTimingAttribute(const std::string& name) {
+  return name == "navigationStart";
+}
+
+DOMHighResTimeStamp ConvertNameToTimestamp(
+    const std::string& name, script::ExceptionState* exception_state) {
+  // The algorithm of ConvertNameToTimestamp() follows these steps:
+  //   https://www.w3.org/TR/user-timing/#convert-a-name-to-a-timestamp
+  // 1. If the global object is not a Window object, throw a SyntaxError.
+  // 2. If name is navigationStart, return 0.
+  if (name == "navigationStart") {
+    return 0.0;
+  }
+
+  // 3. Let startTime be the value of navigationStart in the PerformanceTiming
+  // interface.
+  // 4. Let endTime be the value of name in the PerformanceTiming interface.
+  // 5. If endTime is 0, throw an InvalidAccessError.
+  // 6. Return result of subtracting startTime from endTime.
+
+  // Note that we only support navigationStart in the PerformanceTiming
+  // interface. We return 0.0 instead of the result of subtracting
+  // startTime from endTime.
+  dom::DOMException::Raise(dom::DOMException::kSyntaxErr,
+                           "Cannot convert a name that is not a public "
+                           "attribute of PerformanceTiming to a timestamp",
+                           exception_state);
+  return 0.0;
+}
+
+}  //namespace
+
 Performance::Performance(script::EnvironmentSettings* settings,
                          const scoped_refptr<base::BasicClock>& clock)
     : EventTarget(settings),
-      timing_(new PerformanceTiming(clock)),
+      time_origin_(base::TimeTicks::Now()),
+      tick_clock_(base::DefaultTickClock::GetInstance()),
+      timing_(new PerformanceTiming(clock, time_origin_)),
       memory_(new MemoryInfo()),
-      time_origin_(base::Time::Now() - base::Time::UnixEpoch()),
+      lifecycle_timing_(
+          new PerformanceLifecycleTiming("lifecycle timing", 0.0, 0.0)),
       resource_timing_buffer_size_limit_(
           Performance::kMaxResourceTimingBufferSize),
       resource_timing_buffer_current_size_(0),
       resource_timing_buffer_full_event_pending_flag_(false),
       resource_timing_secondary_buffer_current_size_(0),
       performance_observer_task_queued_flag_(false),
-      add_to_performance_entry_buffer_flag_(false) {}
+      add_to_performance_entry_buffer_flag_(false) {
+  unix_at_zero_monotonic_ = GetUnixAtZeroMonotonic(
+      base::DefaultClock::GetInstance(), tick_clock_);
+  QueuePerformanceEntry(lifecycle_timing_);
+}
+
+// static
+DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
+      base::TimeTicks time_origin,
+      base::TimeTicks monotonic_time) {
+  if (monotonic_time.is_null() || time_origin.is_null())
+    return 0.0;
+  DOMHighResTimeStamp clamped_time =
+      ClampTimeStampMinimumResolution(monotonic_time,
+      Performance::kPerformanceTimerMinResolutionInMicroseconds) -
+      ClampTimeStampMinimumResolution(time_origin,
+      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+
+  if (clamped_time < 0)
+    return 0.0;
+  return clamped_time;
+}
+
+DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
+    base::TimeTicks monotonic_time) const {
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+                                                         monotonic_time);
+}
 
 DOMHighResTimeStamp Performance::Now() const {
-  base::TimeDelta now = base::Time::Now() - base::Time::UnixEpoch();
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      now - time_origin_,
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  // Now stores the current high resolution time.
+  //   https://www.w3.org/TR/2019/REC-hr-time-2-20191121/#dfn-current-high-resolution-time
+  return MonotonicTimeToDOMHighResTimeStamp(tick_clock_->NowTicks());
 }
 
 scoped_refptr<PerformanceTiming> Performance::timing() const { return timing_; }
@@ -51,19 +127,177 @@
   // The algorithm for calculating time origin timestamp.
   //   https://www.w3.org/TR/2019/REC-hr-time-2-20191121/#dfn-time-origin-timestamp
   // Assert that global's time origin is not undefined.
-  DCHECK(!time_origin_.is_zero());
+  DCHECK(!time_origin_.is_null());
 
   // Let t1 be the DOMHighResTimeStamp representing the high resolution
   // time at which the global monotonic clock is zero.
-  base::TimeDelta t1 = base::Time::UnixEpoch().ToDeltaSinceWindowsEpoch();
+  base::TimeDelta t1 = unix_at_zero_monotonic_;
 
   // Let t2 be the DOMHighResTimeStamp representing the high resolution
   // time value of the global monotonic clock at global's time origin.
-  base::TimeDelta t2 = time_origin_;
+  base::TimeDelta t2 = time_origin_ - base::TimeTicks();
 
   // Return the sum of t1 and t2.
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      t1 + t2, Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return ClampTimeStampMinimumResolution(
+      t1 + t2,
+      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+}
+
+void Performance::Mark(const std::string& mark_name,
+                       script::ExceptionState* exception_state) {
+  // The algorithm for mark() follows these steps:
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#mark-method
+  // 1. If the global object is a Window object and markName uses the same name
+  // as a read only attribute in the PerformanceTiming interface, throw a
+  // SyntaxError.
+  if (IsNamePerformanceTimingAttribute(mark_name)) {
+    dom::DOMException::Raise(
+        dom::DOMException::kSyntaxErr,
+        "Cannot create a mark with the same name as a read-only attribute in "
+        "the PerformanceTiming interface",
+        exception_state);
+  }
+
+  // 2. Create a new PerformanceMark object (entry).
+  // 3. Set entry's name attribute to markName.
+  // 4. Set entry's entryType attribute to DOMString "mark".
+  // 5. Set entry's startTime attribute to the value that would be returned by
+  // the Performance object's now() method.
+  // 6. Set entry's duration attribute to 0.
+  scoped_refptr<PerformanceMark> entry =
+      base::MakeRefCounted<PerformanceMark>(mark_name, Now());
+
+  // 7. Queue entry.
+  QueuePerformanceEntry(entry);
+
+  // 8. Add entry to the performance entry buffer.
+  performance_entry_buffer_.push_back(entry);
+
+  // 9. Return undefined
+}
+
+void Performance::ClearMarks(const std::string& mark_name) {
+  // The algorithm for clearMarks follows these steps:
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#clearmarks-method
+  // 1. If markName is omitted, remove all PerformanceMark objects from the
+  // performance entry buffer.
+  // 2. Otherwise, remove all PerformanceMark objects listed in the performance
+  // entry buffer whose name matches markName.
+  PerformanceEntryList retained_performance_entry_buffer;
+  for (const auto& entry : performance_entry_buffer_) {
+    bool should_remove_entry =
+        PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
+            PerformanceEntry::kMark &&
+        (mark_name.empty() || entry->name() == mark_name);
+    if (!should_remove_entry) {
+      retained_performance_entry_buffer.push_back(entry);
+    }
+  }
+  performance_entry_buffer_.swap(retained_performance_entry_buffer);
+
+  // 3. Return undefined.
+}
+
+void Performance::Measure(const std::string& measure_name,
+                          const std::string& start_mark,
+                          const std::string& end_mark,
+                          script::ExceptionState* exception_state) {
+  // The algorithm for measure() follows these steps:
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#measure-method
+  // 1. Let end time be 0.
+  DOMHighResTimeStamp end_time = 0.0;
+
+  // 2. If endMark is omitted, let end time be the value that would be returned
+  // by the Performance object's now() method.
+  if (end_mark.empty()) {
+    end_time = Now();
+  } else if (IsNamePerformanceTimingAttribute(end_mark)) {
+    // 2.1. Otherwise, if endMark has the same name as a read only attribute in
+    // the PerformanceTiming interface, let end time be the value returned by
+    // running the convert a name to a timestamp algorithm with name set to the
+    // value of endMark.
+    end_time = ConvertNameToTimestamp(end_mark, exception_state);
+  } else {
+    // 2.2. Otherwise let end time be the value of the startTime attribute from
+    // the most recent occurrence of a PerformanceMark object in the performance
+    // entry buffer whose name matches the value of endMark. If no matching
+    // entry is found, throw a SyntaxError.
+    PerformanceEntryList list = GetEntriesByName(end_mark, "mark");
+    if (list.empty()) {
+      dom::DOMException::Raise(
+          dom::DOMException::kSyntaxErr,
+          "Cannot create measure; no mark found with name: " + end_mark + ".",
+          exception_state);
+      return;
+    }
+    end_time = list.at(list.size() - 1)->start_time();
+  }
+
+  DOMHighResTimeStamp start_time;
+  // 3. If startMark is omitted, let start time be 0.
+  if (start_mark.empty()) {
+    start_time = 0.0;
+  } else if (IsNamePerformanceTimingAttribute(start_mark)) {
+    // 3.1. If startMark has the same name as a read only attribute in the
+    // PerformanceTiming interface, let start time be the value returned by
+    // running the convert a name to a timestamp algorithm with name set to
+    // startMark.
+    start_time = ConvertNameToTimestamp(start_mark, exception_state);
+  } else {
+    // 3.2. Otherwise let start time be the value of the startTime attribute
+    // from the most recent occurrence of a PerformanceMark object in the
+    // performance entry buffer whose name matches the value of startMark. If no
+    // matching entry is found, throw a SyntaxError.
+    PerformanceEntryList list = GetEntriesByName(start_mark, "mark");
+    if (list.empty()) {
+      dom::DOMException::Raise(
+          dom::DOMException::kSyntaxErr,
+          "Cannot create measure; no mark found with name: " + start_mark + ".",
+          exception_state);
+      return;
+    }
+    start_time = list.at(list.size() - 1)->start_time();
+  }
+
+  // 4. Create a new PerformanceMeasure object (entry).
+  // 5. Set entry's name attribute to measureName.
+  // 6. Set entry's entryType attribute to DOMString "measure".
+  // 7. Set entry's startTime attribute to start time.
+  // 8. Set entry's duration attribute to the duration from start time to end
+  // time. The resulting duration value MAY be negative.
+  scoped_refptr<PerformanceMeasure> entry =
+      base::MakeRefCounted<PerformanceMeasure>(measure_name, start_time,
+                                               end_time);
+
+  // 9. Queue entry.
+  QueuePerformanceEntry(entry);
+
+  // 10. Add entry to the performance entry buffer.
+  performance_entry_buffer_.push_back(entry);
+
+  // 11. Return undefined.
+}
+
+void Performance::ClearMeasures(const std::string& measure_name) {
+  // The algorithm for clearMeasures follows these steps:
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#clearmeasures-method
+  // 1. If measureName is omitted, remove all PerformanceMeasure objects in the
+  // performance entry buffer.
+  // 2. Otherwise remove all PerformanceMeasure objects listed in the
+  // performance entry buffer whose name matches measureName.
+  PerformanceEntryList performance_entry_buffer;
+  for (const auto& entry : performance_entry_buffer_) {
+    bool shouldRemoveEntry =
+        PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
+            PerformanceEntry::kMeasure &&
+        (measure_name.empty() || entry->name() == measure_name);
+    if (!shouldRemoveEntry) {
+      performance_entry_buffer.push_back(entry);
+    }
+  }
+  performance_entry_buffer_.swap(performance_entry_buffer);
+
+  // 3. Return undefined.
 }
 
 void Performance::UnregisterPerformanceObserver(
@@ -83,8 +317,7 @@
     const PerformanceObserverInit& options) {
   std::list<PerformanceObserverInit> options_list;
   options_list.push_back(options);
-  registered_performance_observers_.emplace_back(observer,
-                                                 options_list);
+  registered_performance_observers_.emplace_back(observer, options_list);
 }
 
 void Performance::ReplaceRegisteredPerformanceObserverOptionsList(
@@ -122,6 +355,7 @@
 void Performance::TraceMembers(script::Tracer* tracer) {
   tracer->Trace(timing_);
   tracer->Trace(memory_);
+  tracer->Trace(lifecycle_timing_);
 }
 
 PerformanceEntryList Performance::GetEntries() {
@@ -131,13 +365,13 @@
 PerformanceEntryList Performance::GetEntriesByType(
     const std::string& entry_type) {
   return PerformanceEntryListImpl::GetEntriesByType(performance_entry_buffer_,
-                                                      entry_type);
+                                                    entry_type);
 }
 
 PerformanceEntryList Performance::GetEntriesByName(
     const std::string& name, const base::StringPiece& type) {
   return PerformanceEntryListImpl::GetEntriesByName(performance_entry_buffer_,
-                                                      name, type);
+                                                    name, type);
 }
 
 void Performance::ClearResourceTimings() {
@@ -147,7 +381,9 @@
   // entry buffer.
   PerformanceEntryList performance_entry_buffer;
   for (const auto& entry : performance_entry_buffer_) {
-    if (!base::polymorphic_downcast<PerformanceResourceTiming*>(entry.get())) {
+    bool should_be_removed = PerformanceEntry::ToEntryTypeEnum(
+        entry->entry_type()) == PerformanceEntry::kResource;
+    if (!should_be_removed) {
       performance_entry_buffer.push_back(entry);
     }
   }
@@ -157,7 +393,8 @@
   resource_timing_buffer_current_size_ = 0;
 }
 
-void Performance::SetResourceTimingBufferSize(unsigned long max_size) {
+void Performance::SetResourceTimingBufferSize(
+    unsigned long max_size) {  // NOLINT(runtime/int)
   // The method runs the following steps:
   //   https://www.w3.org/TR/2021/WD-resource-timing-2-20210414/#dom-performance-setresourcetimingbuffersize
   // 1. Set resource timing buffer size limit to the maxSize parameter.
@@ -218,7 +455,7 @@
   while (!resource_timing_secondary_buffer_.empty()) {
     // 1.1 Let number of excess entries before be resource timing secondary
     // buffer current size.
-    unsigned long excess_entries_before =
+    unsigned long excess_entries_before =  // NOLINT(runtime/int)
         resource_timing_secondary_buffer_current_size_;
     // 1.2 If can add resource timing entry returns false, then fire an event
     // named resourcetimingbufferfull at the Performance object.
@@ -229,7 +466,7 @@
     CopySecondaryBuffer();
     // 1.4 Let number of excess entries after be resource timing secondary
     // buffer current size.
-    unsigned long excess_entries_after =
+    unsigned long excess_entries_after =  // NOLINT(runtime/int)
         resource_timing_secondary_buffer_current_size_;
     // 1.5 If number of excess entries before is lower than or equals number of
     // excess entries after, then remove all entries from resource timing
@@ -369,7 +606,7 @@
   // requestedURL, timingInfo, and cacheMode.
   scoped_refptr<PerformanceResourceTiming> resource_timing(
       new PerformanceResourceTiming(timing_info, initiator_type,
-                                    requested_url, this));
+                                    requested_url, this, time_origin_));
   // 2. Queue entry.
   QueuePerformanceEntry(resource_timing);
   // 3. Add entry to global's performance entry buffer.
diff --git a/src/cobalt/dom/performance.h b/src/cobalt/dom/performance.h
index 878271c..e69d9a8 100644
--- a/src/cobalt/dom/performance.h
+++ b/src/cobalt/dom/performance.h
@@ -21,18 +21,21 @@
 #include <string>
 
 #include "cobalt/base/clock.h"
+#include "base/time/default_tick_clock.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_checker.h"
+#include "cobalt/base/clock.h"
 #include "cobalt/dom/event_target.h"
 #include "cobalt/dom/performance_entry_list_impl.h"
 #include "cobalt/dom/performance_high_resolution_time.h"
+#include "cobalt/dom/performance_lifecycle_timing.h"
 #include "cobalt/dom/performance_observer.h"
 #include "cobalt/dom/performance_observer_callback_options.h"
 #include "cobalt/dom/performance_observer_init.h"
 #include "cobalt/dom/performance_resource_timing.h"
 #include "cobalt/dom/performance_timing.h"
 #include "cobalt/script/environment_settings.h"
-
+#include "cobalt/script/exception_state.h"
 #include "net/base/load_timing_info.h"
 
 namespace cobalt {
@@ -49,9 +52,11 @@
   // order to mitigate potential Spectre-related attacks.  This is following
   // Mozilla's lead as described here:
   //   https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/
+  // NOLINT(runtime/int)
   static constexpr int64_t kPerformanceTimerMinResolutionInMicroseconds = 20;
   //   https://www.w3.org/TR/2021/WD-resource-timing-2-20210414/#sec-extensions-performance-interface
-  static constexpr unsigned long kMaxResourceTimingBufferSize = 250;
+  static constexpr unsigned long  // NOLINT(runtime/int)
+      kMaxResourceTimingBufferSize = 250;
 
   Performance(script::EnvironmentSettings* settings,
               const scoped_refptr<base::BasicClock>& clock);
@@ -62,6 +67,12 @@
   scoped_refptr<MemoryInfo> memory() const;
   DOMHighResTimeStamp Now() const;
   DOMHighResTimeStamp time_origin() const;
+  DOMHighResTimeStamp MonotonicTimeToDOMHighResTimeStamp(
+      base::TimeTicks monotonic_time) const;
+
+  static DOMHighResTimeStamp MonotonicTimeToDOMHighResTimeStamp(
+      base::TimeTicks time_origin,
+      base::TimeTicks monotonic_time);
 
   // Web API: Performance Timeline extensions to the Performance.
   //   https://www.w3.org/TR/performance-timeline-2/#extensions-to-the-performance-interface
@@ -70,10 +81,22 @@
   PerformanceEntryList GetEntriesByName(const std::string& name,
                                         const base::StringPiece& type);
 
+  // Web API: User Timing extensions to Performance
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#extensions-performance-interface
+  void Mark(const std::string& mark_name,
+            script::ExceptionState* exception_state);
+  void ClearMarks(const std::string& mark_name);
+  void Measure(const std::string& measure_name, const std::string& start_mark,
+               const std::string& end_mark,
+               script::ExceptionState* exception_state);
+  void ClearMeasures(const std::string& measure_name);
+
   // Web API: Performance Resource Timing extensions to Performance.
   //   https://w3c.github.io/resource-timing/#sec-extensions-performance-interface
   void ClearResourceTimings();
-  void SetResourceTimingBufferSize(unsigned long max_size);
+  // NOLINT(runtime/int)
+  void SetResourceTimingBufferSize(
+      unsigned long max_size);  // NOLINT(runtime/int)
   bool CanAddResourceTimingEntry();
   void CopySecondaryBuffer();
   void set_onresourcetimingbufferfull(
@@ -88,9 +111,12 @@
   void CreatePerformanceResourceTiming(const net::LoadTimingInfo& timing_info,
                                        const std::string& initiator_type,
                                        const std::string& requested_url);
+  void CreatePerformanceLifecycleTiming();
   // Custom, not in any spec.
-  base::TimeDelta get_time_origin() const { return time_origin_; }
-
+  // Internal getter method for the time origin value.
+  base::TimeTicks GetTimeOrigin() const {
+      return time_origin_;
+  }
   // Register and unregisterthe performance observer.
   void UnregisterPerformanceObserver(
       const scoped_refptr<PerformanceObserver>& observer);
@@ -112,9 +138,12 @@
  private:
   unsigned long GetDroppedEntriesCount(const std::string& entry_type);
 
+  base::TimeTicks time_origin_;
+  const base::TickClock* tick_clock_;
   scoped_refptr<PerformanceTiming> timing_;
   scoped_refptr<MemoryInfo> memory_;
-  base::TimeDelta time_origin_;
+  scoped_refptr<PerformanceLifecycleTiming> lifecycle_timing_;
+  base::TimeDelta unix_at_zero_monotonic_;
 
   PerformanceEntryList performance_entry_buffer_;
   struct RegisteredPerformanceObserver : public script::Traceable {
@@ -138,7 +167,8 @@
   unsigned long resource_timing_buffer_size_limit_;
   unsigned long resource_timing_buffer_current_size_;
   bool resource_timing_buffer_full_event_pending_flag_;
-  unsigned long resource_timing_secondary_buffer_current_size_;
+  unsigned long
+      resource_timing_secondary_buffer_current_size_;
   std::deque<scoped_refptr<PerformanceResourceTiming>>
       resource_timing_secondary_buffer_;
 
diff --git a/src/cobalt/dom/performance.idl b/src/cobalt/dom/performance.idl
index fd42dd3..91d2e8e 100644
--- a/src/cobalt/dom/performance.idl
+++ b/src/cobalt/dom/performance.idl
@@ -25,4 +25,14 @@
   void clearResourceTimings ();
   void setResourceTimingBufferSize (unsigned long maxSize);
   attribute EventHandler onresourcetimingbufferfull;
+
+  // Web API: User Timing extensions to Performance
+  //   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#extensions-performance-interface
+  [RaisesException] void mark(DOMString name);
+  [RaisesException] void measure(
+      DOMString measureName,
+      optional DOMString startMark = "",
+      optional DOMString endMark = "");
+  void clearMarks(optional DOMString name = "");
+  void clearMeasures(optional DOMString measureName = "");
 };
diff --git a/src/cobalt/dom/performance_entry.h b/src/cobalt/dom/performance_entry.h
index 8e3a3b7..7617b36 100644
--- a/src/cobalt/dom/performance_entry.h
+++ b/src/cobalt/dom/performance_entry.h
@@ -29,18 +29,20 @@
 //   https://w3c.github.io/performance-timeline/#the-performanceentry-interface
 class PerformanceEntry : public script::Wrappable {
  public:
-  PerformanceEntry(const std::string& name,
-                   DOMHighResTimeStamp start_time,
+  PerformanceEntry(const std::string& name, DOMHighResTimeStamp start_time,
                    DOMHighResTimeStamp finish_time);
 
   enum EntryType : PerformanceEntryType {
     kResource = 0,
     kNavigation = 1,
-    kInvalid = 2,
+    kLifecycle = 2,
+    kMark = 3,
+    kMeasure = 4,
+    kInvalid = 5,
   };
 
-  static constexpr const char* kEntryTypeString[] =
-      {"resource", "navigation", "invalid"};
+  static constexpr const char* kEntryTypeString[] = {
+      "resource", "navigation", "lifecycle", "mark", "measure", "invalid"};
 
   std::string name() const { return name_; }
   DOMHighResTimeStamp start_time() const;
@@ -53,8 +55,9 @@
   static PerformanceEntry::EntryType ToEntryTypeEnum(
       const std::string& entry_type);
 
-  static bool StartTimeCompareLessThan(const scoped_refptr<PerformanceEntry>& a,
-                                       const scoped_refptr<PerformanceEntry>& b);
+  static bool StartTimeCompareLessThan(
+      const scoped_refptr<PerformanceEntry>& a,
+      const scoped_refptr<PerformanceEntry>& b);
 
   DEFINE_WRAPPABLE_TYPE(PerformanceEntry);
 
diff --git a/src/cobalt/dom/performance_high_resolution_time.h b/src/cobalt/dom/performance_high_resolution_time.h
index 3246964..5033e5b 100644
--- a/src/cobalt/dom/performance_high_resolution_time.h
+++ b/src/cobalt/dom/performance_high_resolution_time.h
@@ -41,20 +41,21 @@
 
 // Clamp customized minimum clock resolution.
 //   https://w3c.github.io/hr-time/#clock-resolution
-inline base::TimeDelta ClampTimeStampMinimumResolution(base::TimeDelta delta,
+inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(
+    base::TimeTicks ticks,
+    int64_t min_resolution_in_microseconds) {
+    int64_t microseconds = ticks.ToInternalValue();
+    return base::TimeDelta::FromMicroseconds(microseconds -
+        (microseconds % min_resolution_in_microseconds)).InMillisecondsF();
+}
+
+// Clamp customized minimum clock resolution.
+//   https://w3c.github.io/hr-time/#clock-resolution
+inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(base::TimeDelta delta,
     int64_t min_resolution_in_microseconds) {
     int64_t microseconds = delta.InMicroseconds();
     return base::TimeDelta::FromMicroseconds(microseconds -
-        (microseconds % min_resolution_in_microseconds));
-}
-
-// Clamp customized minimum clock resolution and convet TimeDelta
-// to DOMHighResTimeStamp.
-inline DOMHighResTimeStamp ConvertTimeDeltaToDOMHighResTimeStamp(
-    base::TimeDelta delta, int64_t min_resolution_in_microseconds) {
-  base::TimeDelta clamp_delta =
-      ClampTimeStampMinimumResolution(delta, min_resolution_in_microseconds);
-  return clamp_delta.InMillisecondsF();
+        (microseconds % min_resolution_in_microseconds)).InMicrosecondsF();
 }
 
 }  // namespace dom
diff --git a/src/cobalt/dom/performance_lifecycle_timing.cc b/src/cobalt/dom/performance_lifecycle_timing.cc
new file mode 100644
index 0000000..6b64ff4
--- /dev/null
+++ b/src/cobalt/dom/performance_lifecycle_timing.cc
@@ -0,0 +1,70 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "cobalt/dom/performance_lifecycle_timing.h"
+#include "cobalt/dom/performance.h"
+
+namespace cobalt {
+namespace dom {
+
+PerformanceLifecycleTiming::PerformanceLifecycleTiming(
+    const std::string& name, DOMHighResTimeStamp start_time,
+    DOMHighResTimeStamp end_time)
+    : PerformanceEntry(name, start_time, end_time),
+    current_state_("unstarted"),
+    last_state_("unstarted") {}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_start() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_blur() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_focus() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_conceal() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_reveal() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_freeze() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_unfreeze() const {
+  return PerformanceEntry::start_time();
+}
+
+DOMHighResTimeStamp PerformanceLifecycleTiming::app_stop() const {
+  return PerformanceEntry::start_time();
+}
+
+std::string PerformanceLifecycleTiming::current_state() const {
+  return current_state_;
+}
+
+std::string PerformanceLifecycleTiming::last_state() const {
+  return last_state_;
+}
+
+}  // namespace dom
+}  // namespace cobalt
\ No newline at end of file
diff --git a/src/cobalt/dom/performance_lifecycle_timing.h b/src/cobalt/dom/performance_lifecycle_timing.h
new file mode 100644
index 0000000..08a3415
--- /dev/null
+++ b/src/cobalt/dom/performance_lifecycle_timing.h
@@ -0,0 +1,65 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_PERFORMANCE_LIFECYCLE_TIMING_H_
+#define COBALT_DOM_PERFORMANCE_LIFECYCLE_TIMING_H_
+
+#include <string>
+
+#include "cobalt/dom/performance_entry.h"
+#include "cobalt/dom/performance_high_resolution_time.h"
+
+#include "cobalt/script/wrappable.h"
+#include "net/base/load_timing_info.h"
+
+namespace cobalt {
+namespace dom {
+
+class Performance;
+
+class PerformanceLifecycleTiming : public PerformanceEntry {
+ public:
+  PerformanceLifecycleTiming(const std::string& name,
+                            DOMHighResTimeStamp start_time,
+                            DOMHighResTimeStamp end_time);
+
+  // Web API.
+  DOMHighResTimeStamp app_start() const;
+  DOMHighResTimeStamp app_blur() const;
+  DOMHighResTimeStamp app_focus() const;
+  DOMHighResTimeStamp app_conceal() const;
+  DOMHighResTimeStamp app_reveal() const;
+  DOMHighResTimeStamp app_freeze() const;
+  DOMHighResTimeStamp app_unfreeze() const;
+  DOMHighResTimeStamp app_stop() const;
+  std::string current_state() const;
+  std::string last_state() const;
+
+  std::string entry_type() const override { return "lifecycle"; }
+  PerformanceEntryType EntryTypeEnum() const override {
+    return PerformanceEntry::kLifecycle;
+  }
+
+  DEFINE_WRAPPABLE_TYPE(PerformanceLifecycleTiming);
+
+ private:
+  std::string current_state_;
+  std::string last_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(PerformanceLifecycleTiming);
+};
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_PERFORMANCE_LIFECYCLE_TIMING_H_
\ No newline at end of file
diff --git a/src/cobalt/dom/performance_lifecycle_timing.idl b/src/cobalt/dom/performance_lifecycle_timing.idl
new file mode 100644
index 0000000..602331d
--- /dev/null
+++ b/src/cobalt/dom/performance_lifecycle_timing.idl
@@ -0,0 +1,27 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+[Exposed=Window]
+interface PerformanceLifecycleTiming : PerformanceEntry {
+  readonly  attribute DOMHighResTimeStamp appStart;
+  readonly  attribute DOMHighResTimeStamp appBlur;
+  readonly  attribute DOMHighResTimeStamp appFocus;
+  readonly  attribute DOMHighResTimeStamp appConceal;
+  readonly  attribute DOMHighResTimeStamp appReveal;
+  readonly  attribute DOMHighResTimeStamp appFreeze;
+  readonly  attribute DOMHighResTimeStamp appUnfreeze;
+  readonly  attribute DOMHighResTimeStamp appStop;
+  readonly  attribute DOMString  currentState;
+  readonly  attribute DOMString  lastState;
+};
diff --git a/src/cobalt/dom/performance_mark.cc b/src/cobalt/dom/performance_mark.cc
new file mode 100644
index 0000000..0efdf5b
--- /dev/null
+++ b/src/cobalt/dom/performance_mark.cc
@@ -0,0 +1,28 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cobalt/dom/performance_mark.h"
+
+#include "cobalt/dom/performance.h"
+#include "cobalt/dom/performance_entry.h"
+
+namespace cobalt {
+namespace dom {
+
+PerformanceMark::PerformanceMark(const std::string& name,
+                                 DOMHighResTimeStamp start_time)
+    : PerformanceEntry(name, start_time, start_time) {}
+
+}  // namespace dom
+}  // namespace cobalt
diff --git a/src/cobalt/dom/performance_mark.h b/src/cobalt/dom/performance_mark.h
new file mode 100644
index 0000000..7d477b6
--- /dev/null
+++ b/src/cobalt/dom/performance_mark.h
@@ -0,0 +1,45 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_PERFORMANCE_MARK_H_
+#define COBALT_DOM_PERFORMANCE_MARK_H_
+
+#include <string>
+
+#include "cobalt/dom/performance_entry.h"
+#include "cobalt/dom/performance_high_resolution_time.h"
+#include "cobalt/script/wrappable.h"
+#include "net/base/load_timing_info.h"
+
+namespace cobalt {
+namespace dom {
+class Performance;
+
+// Implements the PerformanceMart interface.
+//   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#performancemark
+class PerformanceMark : public PerformanceEntry {
+ public:
+  PerformanceMark(const std::string& name, DOMHighResTimeStamp start_time);
+
+  std::string entry_type() const override { return "mark"; }
+  PerformanceEntryType EntryTypeEnum() const override {
+    return PerformanceEntry::kMark;
+  }
+
+  DEFINE_WRAPPABLE_TYPE(PerformanceMark);
+};
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_PERFORMANCE_MARK_H_
diff --git a/src/starboard/linux/x64x11/clang/3.6/atomic_public.h b/src/cobalt/dom/performance_mark.idl
similarity index 65%
copy from src/starboard/linux/x64x11/clang/3.6/atomic_public.h
copy to src/cobalt/dom/performance_mark.idl
index 9031c7b..834479b 100644
--- a/src/starboard/linux/x64x11/clang/3.6/atomic_public.h
+++ b/src/cobalt/dom/performance_mark.idl
@@ -1,4 +1,4 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,9 +12,5 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
-#define STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
-
-#include "starboard/linux/x64x11/atomic_public.h"
-
-#endif  // STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
+[Exposed=Window]
+interface PerformanceMark : PerformanceEntry {};
diff --git a/src/cobalt/dom/performance_measure.cc b/src/cobalt/dom/performance_measure.cc
new file mode 100644
index 0000000..1a7edfb
--- /dev/null
+++ b/src/cobalt/dom/performance_measure.cc
@@ -0,0 +1,29 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cobalt/dom/performance_measure.h"
+
+#include "cobalt/dom/performance.h"
+#include "cobalt/dom/performance_entry.h"
+
+namespace cobalt {
+namespace dom {
+
+PerformanceMeasure::PerformanceMeasure(const std::string& name,
+                                       DOMHighResTimeStamp start_time,
+                                       DOMHighResTimeStamp end_time)
+    : PerformanceEntry(name, start_time, end_time) {}
+
+}  // namespace dom
+}  // namespace cobalt
diff --git a/src/cobalt/dom/performance_measure.h b/src/cobalt/dom/performance_measure.h
new file mode 100644
index 0000000..41107c3
--- /dev/null
+++ b/src/cobalt/dom/performance_measure.h
@@ -0,0 +1,46 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_PERFORMANCE_MEASURE_H_
+#define COBALT_DOM_PERFORMANCE_MEASURE_H_
+
+#include <string>
+
+#include "cobalt/dom/performance_entry.h"
+#include "cobalt/dom/performance_high_resolution_time.h"
+#include "cobalt/script/wrappable.h"
+#include "net/base/load_timing_info.h"
+
+namespace cobalt {
+namespace dom {
+class Performance;
+
+// Implements the PerformanceMeasure interface.
+//   https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#performancemeasure
+class PerformanceMeasure : public PerformanceEntry {
+ public:
+  PerformanceMeasure(const std::string& name, DOMHighResTimeStamp start_time,
+                     DOMHighResTimeStamp end_time);
+
+  std::string entry_type() const override { return "measure"; }
+  PerformanceEntryType EntryTypeEnum() const override {
+    return PerformanceEntry::kMeasure;
+  }
+
+  DEFINE_WRAPPABLE_TYPE(PerformanceMeasure);
+};
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_PERFORMANCE_MEASURE_H_
diff --git a/src/starboard/linux/x64x11/clang/3.6/atomic_public.h b/src/cobalt/dom/performance_measure.idl
similarity index 65%
copy from src/starboard/linux/x64x11/clang/3.6/atomic_public.h
copy to src/cobalt/dom/performance_measure.idl
index 9031c7b..b6cb447 100644
--- a/src/starboard/linux/x64x11/clang/3.6/atomic_public.h
+++ b/src/cobalt/dom/performance_measure.idl
@@ -1,4 +1,4 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,9 +12,5 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
-#define STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
-
-#include "starboard/linux/x64x11/atomic_public.h"
-
-#endif  // STARBOARD_LINUX_X64X11_CLANG_3_6_ATOMIC_PUBLIC_H_
+[Exposed=Window]
+interface PerformanceMeasure : PerformanceEntry {};
diff --git a/src/cobalt/dom/performance_resource_timing.cc b/src/cobalt/dom/performance_resource_timing.cc
index eb48afe..11dac39 100644
--- a/src/cobalt/dom/performance_resource_timing.cc
+++ b/src/cobalt/dom/performance_resource_timing.cc
@@ -29,70 +29,86 @@
 
 PerformanceResourceTiming::PerformanceResourceTiming(
     const net::LoadTimingInfo& timing_info, const std::string& initiator_type,
-    const std::string& requested_url, Performance* performance)
+    const std::string& requested_url, Performance* performance,
+    base::TimeTicks time_origin)
     : PerformanceEntry(
-          requested_url, performance->Now(),
-          ConvertTimeDeltaToDOMHighResTimeStamp(
-              timing_info.receive_headers_end.since_origin(),
-              Performance::kPerformanceTimerMinResolutionInMicroseconds)),
+          requested_url,
+          Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin,
+              timing_info.request_start),
+          Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin,
+              timing_info.receive_headers_end)),
       initiator_type_(initiator_type),
       cache_mode_(kPerformanceResourceTimingCacheMode),
       transfer_size_(0),
-      timing_info_(timing_info) {}
+      timing_info_(timing_info),
+      time_origin_(time_origin) {}
 
 std::string PerformanceResourceTiming::initiator_type() const {
   return initiator_type_;
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::fetch_start() const {
-  // There is no worker in Cobalt, thus we need to return start_time()
-  // instead of worker ready time.
-  return PerformanceEntry::start_time();
+  if (timing_info_.request_start.is_null()) {
+    return PerformanceEntry::start_time();
+  }
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.request_start);
+}
+
+DOMHighResTimeStamp PerformanceResourceTiming::domain_lookup_start() const {
+  if (timing_info_.connect_timing.dns_start.is_null()) {
+    return PerformanceEntry::start_time();
+  }
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.connect_timing.dns_start);
+}
+
+DOMHighResTimeStamp PerformanceResourceTiming::domain_lookup_end() const {
+  if (timing_info_.connect_timing.dns_end.is_null()) {
+    return PerformanceEntry::start_time();
+  }
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.connect_timing.dns_end);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::connect_start() const {
   if (timing_info_.connect_timing.connect_start.is_null()) {
     return PerformanceEntry::start_time();
   }
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      timing_info_.connect_timing.connect_start.since_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.connect_timing.connect_start);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::connect_end() const {
   if (timing_info_.connect_timing.connect_end.is_null()) {
     return PerformanceEntry::start_time();
   }
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      timing_info_.connect_timing.connect_end.since_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.connect_timing.connect_end);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::secure_connection_start() const {
   if (timing_info_.connect_timing.ssl_start.is_null()) {
     return 0.0;
   }
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      timing_info_.connect_timing.ssl_start.since_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.connect_timing.ssl_start);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::request_start() const {
   if (timing_info_.send_start.is_null()) {
     return PerformanceEntry::start_time();
   }
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      timing_info_.send_start.since_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.send_start);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::response_start() const {
   if (timing_info_.receive_headers_end.is_null()) {
     PerformanceEntry::start_time();
   }
-  return ConvertTimeDeltaToDOMHighResTimeStamp(
-      timing_info_.receive_headers_end.since_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  return Performance::MonotonicTimeToDOMHighResTimeStamp(time_origin_,
+      timing_info_.receive_headers_end);
 }
 
 DOMHighResTimeStamp PerformanceResourceTiming::response_end() const {
diff --git a/src/cobalt/dom/performance_resource_timing.h b/src/cobalt/dom/performance_resource_timing.h
index a0eaa0a..cab3c48 100644
--- a/src/cobalt/dom/performance_resource_timing.h
+++ b/src/cobalt/dom/performance_resource_timing.h
@@ -39,11 +39,14 @@
   PerformanceResourceTiming(const net::LoadTimingInfo& timing_info,
                             const std::string& initiator_type,
                             const std::string& requested_url,
-                            Performance* performance);
+                            Performance* performance,
+                            base::TimeTicks time_origin);
 
   // Web API.
   std::string initiator_type() const;
   DOMHighResTimeStamp fetch_start() const;
+  DOMHighResTimeStamp domain_lookup_start() const;
+  DOMHighResTimeStamp domain_lookup_end() const;
   DOMHighResTimeStamp connect_start() const;
   DOMHighResTimeStamp connect_end() const;
   DOMHighResTimeStamp secure_connection_start() const;
@@ -73,6 +76,7 @@
   uint64_t transfer_size_;
   std::string requested_url_;
   net::LoadTimingInfo timing_info_;
+  base::TimeTicks time_origin_;
 
   DISALLOW_COPY_AND_ASSIGN(PerformanceResourceTiming);
 };
diff --git a/src/cobalt/dom/performance_resource_timing.idl b/src/cobalt/dom/performance_resource_timing.idl
index 95dc923..c1c0bd3 100644
--- a/src/cobalt/dom/performance_resource_timing.idl
+++ b/src/cobalt/dom/performance_resource_timing.idl
@@ -18,6 +18,8 @@
 interface PerformanceResourceTiming : PerformanceEntry {
   readonly  attribute DOMString           initiatorType;
   readonly  attribute DOMHighResTimeStamp fetchStart;
+  readonly  attribute DOMHighResTimeStamp domainLookupStart;
+  readonly  attribute DOMHighResTimeStamp domainLookupEnd;
   readonly  attribute DOMHighResTimeStamp connectStart;
   readonly  attribute DOMHighResTimeStamp connectEnd;
   readonly  attribute DOMHighResTimeStamp secureConnectionStart;
diff --git a/src/cobalt/dom/performance_test.cc b/src/cobalt/dom/performance_test.cc
index 6f5e55c..be1e776 100644
--- a/src/cobalt/dom/performance_test.cc
+++ b/src/cobalt/dom/performance_test.cc
@@ -29,48 +29,36 @@
 
   // Test that now returns a result that is within a correct range for the
   // current time.
-  base::TimeDelta lower_limit = base::Time::Now() - base::Time::UnixEpoch();
+  DOMHighResTimeStamp lower_limit =
+      performance->MonotonicTimeToDOMHighResTimeStamp(base::TimeTicks::Now());
 
   DOMHighResTimeStamp current_time_in_milliseconds = performance->Now();
 
-  base::TimeDelta upper_limit = base::Time::Now() - base::Time::UnixEpoch();
+  DOMHighResTimeStamp upper_limit =
+      performance->MonotonicTimeToDOMHighResTimeStamp(base::TimeTicks::Now());
 
-  DCHECK_GE(current_time_in_milliseconds, ConvertTimeDeltaToDOMHighResTimeStamp(
-      lower_limit - performance->get_time_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds));
-  DCHECK_LE(current_time_in_milliseconds, ConvertTimeDeltaToDOMHighResTimeStamp(
-      upper_limit - performance->get_time_origin(),
-      Performance::kPerformanceTimerMinResolutionInMicroseconds));
+  DCHECK_GE(current_time_in_milliseconds, lower_limit);
+  DCHECK_LE(current_time_in_milliseconds, upper_limit);
 }
 
-TEST(PerformanceTest, TimeOrigin) {
+TEST(PerformanceTest, MonotonicTimeToDOMHighResTimeStamp) {
   scoped_refptr<base::SystemMonotonicClock> clock(
       new base::SystemMonotonicClock());
-  // Test that time_origin returns a result that is within a correct range for
-  // the current time.
-  base::Time lower_limit = base::Time::Now();
 
   testing::StubEnvironmentSettings environment_settings;
   scoped_refptr<Performance> performance(new Performance(&environment_settings, clock));
 
-  base::Time upper_limit = base::Time::Now();
+  base::TimeTicks current_time_ticks = base::TimeTicks::Now();
+  DOMHighResTimeStamp  current_time = ClampTimeStampMinimumResolution(
+      current_time_ticks,
+      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+  DOMHighResTimeStamp current_time_respect_to_time_origin =
+      performance->MonotonicTimeToDOMHighResTimeStamp(current_time_ticks);
+  DOMHighResTimeStamp time_origin = ClampTimeStampMinimumResolution(
+      performance->GetTimeOrigin(),
+      Performance::kPerformanceTimerMinResolutionInMicroseconds);
 
-  base::TimeDelta lower_limit_delta = lower_limit - base::Time::UnixEpoch();
-  base::TimeDelta upper_limit_delta = upper_limit - base::Time::UnixEpoch();
-
-  base::TimeDelta time_zero =
-      base::Time::UnixEpoch().ToDeltaSinceWindowsEpoch();
-
-  DOMHighResTimeStamp lower_limit_milliseconds =
-        ConvertTimeDeltaToDOMHighResTimeStamp(lower_limit_delta + time_zero,
-            Performance::kPerformanceTimerMinResolutionInMicroseconds);
-
-  DOMHighResTimeStamp upper_limit_milliseconds =
-        ConvertTimeDeltaToDOMHighResTimeStamp(upper_limit_delta + time_zero,
-            Performance::kPerformanceTimerMinResolutionInMicroseconds);
-
-  DCHECK_GE(performance->time_origin(), lower_limit_milliseconds);
-  DCHECK_LE(performance->time_origin(), upper_limit_milliseconds);
+  DCHECK_EQ(current_time_respect_to_time_origin, current_time - time_origin);
 }
 
 TEST(PerformanceTest, NavigationStart) {
@@ -82,19 +70,17 @@
   // the object will be created at the beginning of a new navigation.
   scoped_refptr<base::SystemMonotonicClock> clock(
       new base::SystemMonotonicClock());
-  base::Time lower_limit = base::Time::Now();
+  base::TimeTicks lower_limit = base::TimeTicks::Now();
 
   scoped_refptr<PerformanceTiming> performance_timing(
-      new PerformanceTiming(clock));
+      new PerformanceTiming(clock, base::TimeTicks::Now()));
 
-  base::Time upper_limit = base::Time::Now();
+  base::TimeTicks upper_limit = base::TimeTicks::Now();
 
   DCHECK_GE(performance_timing->navigation_start(),
-            static_cast<uint64>(
-                (lower_limit - base::Time::UnixEpoch()).InMilliseconds()));
+            static_cast<uint64>((lower_limit.ToInternalValue())));
   DCHECK_LE(performance_timing->navigation_start(),
-            static_cast<uint64>(
-                (upper_limit - base::Time::UnixEpoch()).InMilliseconds()));
+            static_cast<uint64>((upper_limit.ToInternalValue())));
 }
 
 }  // namespace dom
diff --git a/src/cobalt/dom/performance_timing.cc b/src/cobalt/dom/performance_timing.cc
index 6f5783c..910eb03 100644
--- a/src/cobalt/dom/performance_timing.cc
+++ b/src/cobalt/dom/performance_timing.cc
@@ -18,14 +18,15 @@
 namespace dom {
 
 PerformanceTiming::PerformanceTiming(
-    const scoped_refptr<base::BasicClock>& clock)
-    : navigation_start_(base::Time::Now() - base::Time::UnixEpoch()),
+    const scoped_refptr<base::BasicClock>& clock,
+    base::TimeTicks time_origin)
+    : navigation_start_(time_origin),
       navigation_start_clock_(new base::OffsetClock(clock, clock->Now())) {}
 
 PerformanceTiming::~PerformanceTiming() {}
 
 uint64 PerformanceTiming::navigation_start() const {
-  return static_cast<uint64>(navigation_start_.InMilliseconds());
+  return static_cast<uint64>(navigation_start_.ToInternalValue());
 }
 
 scoped_refptr<base::OffsetClock> PerformanceTiming::GetNavigationStartClock() {
diff --git a/src/cobalt/dom/performance_timing.h b/src/cobalt/dom/performance_timing.h
index 71e936d..184d92d 100644
--- a/src/cobalt/dom/performance_timing.h
+++ b/src/cobalt/dom/performance_timing.h
@@ -15,10 +15,9 @@
 #ifndef COBALT_DOM_PERFORMANCE_TIMING_H_
 #define COBALT_DOM_PERFORMANCE_TIMING_H_
 
-#include "cobalt/script/wrappable.h"
-
 #include "base/time/time.h"
 #include "cobalt/base/clock.h"
+#include "cobalt/script/wrappable.h"
 
 namespace cobalt {
 namespace dom {
@@ -26,8 +25,11 @@
 // Implements the PerformanceTiming IDL interface, as described here:
 //   https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#sec-navigation-timing-interface
 class PerformanceTiming : public script::Wrappable {
+  // If any new public fields are added here, handling logic must be added to
+  // Performance::Mark and Performance::Measure.
  public:
-  explicit PerformanceTiming(const scoped_refptr<base::BasicClock>& clock);
+  explicit PerformanceTiming(const scoped_refptr<base::BasicClock>& clock,
+                             base::TimeTicks time_origin);
 
   // This attribute must return the time immediately after the user agent
   // finishes prompting to unload the previous document. If there is no previous
@@ -48,7 +50,7 @@
   ~PerformanceTiming();
 
   // The navigation start time relative to January 1, 1970.
-  base::TimeDelta navigation_start_;
+  base::TimeTicks navigation_start_;
   scoped_refptr<base::OffsetClock> navigation_start_clock_;
 
   DISALLOW_COPY_AND_ASSIGN(PerformanceTiming);
diff --git a/src/cobalt/dom/source_buffer.cc b/src/cobalt/dom/source_buffer.cc
index a217666..de6fd76 100644
--- a/src/cobalt/dom/source_buffer.cc
+++ b/src/cobalt/dom/source_buffer.cc
@@ -413,7 +413,7 @@
       pending_append_data_.reset(new uint8_t[size]);
       pending_append_data_capacity_ = size;
     }
-    SbMemoryCopy(pending_append_data_.get(), data, size);
+    memcpy(pending_append_data_.get(), data, size);
   }
   pending_append_data_size_ = size;
   pending_append_data_offset_ = 0;
diff --git a/src/cobalt/dom/testing/stub_window.h b/src/cobalt/dom/testing/stub_window.h
index 3107483..56def70 100644
--- a/src/cobalt/dom/testing/stub_window.h
+++ b/src/cobalt/dom/testing/stub_window.h
@@ -17,6 +17,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/callback.h"
@@ -72,7 +73,7 @@
         fetcher_factory_.get(), loader_factory_.get(), NULL, NULL, NULL, NULL,
         NULL, NULL, &local_storage_database_, NULL, NULL, NULL, NULL,
         global_environment_->script_value_factory(), NULL,
-        dom_stat_tracker_.get(), url_, "", "en-US", "en",
+        dom_stat_tracker_.get(), url_, "", NULL, "en-US", "en",
         base::Callback<void(const GURL&)>(),
         base::Bind(&StubLoadCompleteCallback), NULL,
         network_bridge::PostSender(), csp::kCSPRequired,
diff --git a/src/cobalt/dom/user_agent_platform_info.h b/src/cobalt/dom/user_agent_platform_info.h
new file mode 100644
index 0000000..a63c8a5
--- /dev/null
+++ b/src/cobalt/dom/user_agent_platform_info.h
@@ -0,0 +1,60 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_USER_AGENT_PLATFORM_INFO_H_
+#define COBALT_DOM_USER_AGENT_PLATFORM_INFO_H_
+
+#include <string>
+
+#include "base/optional.h"
+#include "starboard/system.h"
+
+namespace cobalt {
+namespace dom {
+
+// This class gives the DOM an interface to the user agent platform info. This
+// allows NavigatorUAData to access user agent string info.
+class UserAgentPlatformInfo {
+ public:
+  virtual ~UserAgentPlatformInfo() {}
+
+  virtual const std::string& starboard_version() const = 0;
+  virtual const std::string& os_name_and_version() const = 0;
+  virtual base::Optional<std::string> original_design_manufacturer() const = 0;
+  virtual SbSystemDeviceType device_type() const = 0;
+  virtual const std::string& device_type_string() const = 0;
+  virtual base::Optional<std::string> chipset_model_number() const = 0;
+  virtual base::Optional<std::string> model_year() const = 0;
+  virtual base::Optional<std::string> firmware_version() const = 0;
+  virtual base::Optional<std::string> brand() const = 0;
+  virtual base::Optional<std::string> model() const = 0;
+  virtual const std::string& aux_field() const = 0;
+  virtual base::Optional<SbSystemConnectionType> connection_type() const = 0;
+  virtual const std::string& connection_type_string() const = 0;
+  virtual const std::string& javascript_engine_version() const = 0;
+  virtual const std::string& rasterizer_type() const = 0;
+  virtual const std::string& evergreen_version() const = 0;
+
+  virtual const std::string& cobalt_version() const = 0;
+  virtual const std::string& cobalt_build_version_number() const = 0;
+  virtual const std::string& build_configuration() const = 0;
+
+ protected:
+  UserAgentPlatformInfo() {}
+};
+
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_USER_AGENT_PLATFORM_INFO_H_
diff --git a/src/cobalt/dom/video_track.h b/src/cobalt/dom/video_track.h
index c3078a3..00235da 100644
--- a/src/cobalt/dom/video_track.h
+++ b/src/cobalt/dom/video_track.h
@@ -60,13 +60,13 @@
   //
   static bool IsValidKind(const char* kind) {
     // https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-videotrack-videotrackkind
-    return SbStringCompareAll(kind, "alternative") == 0 ||
-           SbStringCompareAll(kind, "captions") == 0 ||
-           SbStringCompareAll(kind, "main") == 0 ||
-           SbStringCompareAll(kind, "sign") == 0 ||
-           SbStringCompareAll(kind, "subtitles") == 0 ||
-           SbStringCompareAll(kind, "commentary") == 0 ||
-           SbStringGetLength(kind) == 0;
+    return strcmp(kind, "alternative") == 0 ||
+           strcmp(kind, "captions") == 0 ||
+           strcmp(kind, "main") == 0 ||
+           strcmp(kind, "sign") == 0 ||
+           strcmp(kind, "subtitles") == 0 ||
+           strcmp(kind, "commentary") == 0 ||
+           strlen(kind) == 0;
   }
 
   // Reset selected flag without notifying the media element.  This is used by
diff --git a/src/cobalt/dom/window.cc b/src/cobalt/dom/window.cc
index c10512c..c95ed07 100644
--- a/src/cobalt/dom/window.cc
+++ b/src/cobalt/dom/window.cc
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -102,8 +103,8 @@
     script::ScriptValueFactory* script_value_factory,
     MediaSource::Registry* media_source_registry,
     DomStatTracker* dom_stat_tracker, const GURL& url,
-    const std::string& user_agent, const std::string& language,
-    const std::string& font_language_script,
+    const std::string& user_agent, UserAgentPlatformInfo* platform_info,
+    const std::string& language, const std::string& font_language_script,
     const base::Callback<void(const GURL&)> navigation_callback,
     const loader::Decoder::OnCompleteFunction& load_complete_callback,
     network_bridge::CookieJar* cookie_jar,
@@ -159,7 +160,7 @@
               csp_insecure_allowed_token, dom_max_element_depth)))),
       document_loader_(nullptr),
       history_(new History()),
-      navigator_(new Navigator(settings, user_agent, language,
+      navigator_(new Navigator(settings, user_agent, platform_info, language,
                                captions, script_value_factory)),
       ALLOW_THIS_IN_INITIALIZER_LIST(
           relay_on_load_event_(new RelayLoadEvent(this))),
@@ -700,8 +701,7 @@
   tracer->Trace(on_screen_keyboard_);
 }
 
-const scoped_refptr<media_session::MediaSession>
-    Window::media_session() const {
+const scoped_refptr<media_session::MediaSession> Window::media_session() const {
   return navigator_->media_session();
 }
 
diff --git a/src/cobalt/dom/window.h b/src/cobalt/dom/window.h
index 5998432..dce79c2 100644
--- a/src/cobalt/dom/window.h
+++ b/src/cobalt/dom/window.h
@@ -48,6 +48,7 @@
 #include "cobalt/dom/test_runner.h"
 #endif  // ENABLE_TEST_RUNNER
 #include "cobalt/dom/url_registry.h"
+#include "cobalt/dom/user_agent_platform_info.h"
 #include "cobalt/dom/window_timers.h"
 #include "cobalt/input/camera_3d.h"
 #include "cobalt/loader/cors_preflight_cache.h"
@@ -152,8 +153,8 @@
       script::ScriptValueFactory* script_value_factory,
       MediaSourceRegistry* media_source_registry,
       DomStatTracker* dom_stat_tracker, const GURL& url,
-      const std::string& user_agent, const std::string& language,
-      const std::string& font_language_script,
+      const std::string& user_agent, UserAgentPlatformInfo* platform_info,
+      const std::string& language, const std::string& font_language_script,
       const base::Callback<void(const GURL&)> navigation_callback,
       const loader::Decoder::OnCompleteFunction& load_complete_callback,
       network_bridge::CookieJar* cookie_jar,
@@ -349,9 +350,9 @@
   void SetCamera3D(const scoped_refptr<input::Camera3D>& camera_3d);
 
   void set_web_media_player_factory(
-    media::WebMediaPlayerFactory* web_media_player_factory) {
-  html_element_context_->set_web_media_player_factory(
-      web_media_player_factory);
+      media::WebMediaPlayerFactory* web_media_player_factory) {
+    html_element_context_->set_web_media_player_factory(
+        web_media_player_factory);
   }
 
   // Sets the current application state, forwarding on to the
@@ -405,8 +406,7 @@
 
   bool enable_map_to_mesh() { return enable_map_to_mesh_; }
 
-  const scoped_refptr<media_session::MediaSession>
-      media_session() const;
+  const scoped_refptr<media_session::MediaSession> media_session() const;
 
   DEFINE_WRAPPABLE_TYPE(Window);
 
diff --git a/src/cobalt/dom/window_test.cc b/src/cobalt/dom/window_test.cc
index 6c39af9..b7df5f7 100644
--- a/src/cobalt/dom/window_test.cc
+++ b/src/cobalt/dom/window_test.cc
@@ -72,7 +72,8 @@
         css_parser_.get(), dom_parser_.get(), fetcher_factory_.get(), NULL,
         NULL, NULL, NULL, NULL, NULL, NULL, &local_storage_database_, NULL,
         NULL, NULL, NULL, global_environment_->script_value_factory(), NULL,
-        NULL, url_, "", "en-US", "en", base::Callback<void(const GURL &)>(),
+        NULL, url_, "", NULL, "en-US", "en",
+        base::Callback<void(const GURL &)>(),
         base::Bind(&MockErrorCallback::Run,
                    base::Unretained(&mock_error_callback_)),
         NULL, network_bridge::PostSender(), csp::kCSPRequired,
diff --git a/src/cobalt/dom_parser/libxml_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
index d1a6ec1..4642ab1 100644
--- a/src/cobalt/dom_parser/libxml_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
@@ -12,10 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#if defined(STARBOARD)
-#include "starboard/client_porting/poem/string_leaks_poem.h"
-#endif  // defined(STARBOARD)
-
 #include "cobalt/dom_parser/libxml_parser_wrapper.h"
 
 #include "base/logging.h"
diff --git a/src/cobalt/dom_parser/parser.cc b/src/cobalt/dom_parser/parser.cc
index ab8b400..060886a 100644
--- a/src/cobalt/dom_parser/parser.cc
+++ b/src/cobalt/dom_parser/parser.cc
@@ -14,10 +14,6 @@
 
 #include <memory>
 
-#if defined(STARBOARD)
-#include "starboard/client_porting/poem/string_leaks_poem.h"
-#endif  // defined(STARBOARD)
-
 #include "cobalt/dom_parser/parser.h"
 
 #include "base/logging.h"
diff --git a/src/cobalt/extension/configuration.h b/src/cobalt/extension/configuration.h
index 7c12817..4dc64d3 100644
--- a/src/cobalt/extension/configuration.h
+++ b/src/cobalt/extension/configuration.h
@@ -178,12 +178,8 @@
   int (*CobaltSkiaGlyphAtlasWidth)();
   int (*CobaltSkiaGlyphAtlasHeight)();
 
-  // Determines the size of garbage collection threshold. After this many
-  // bytes have been allocated, the SpiderMonkey garbage collector will run.
-  // Lowering this has been found to reduce performance and decrease
-  // JavaScript memory usage. For example, we have measured on at least one
-  // platform that performance becomes 7% worse on average in certain cases
-  // when adjusting this number from 8MB to 1MB.
+  // This configuration has been deprecated and is only kept for
+  // backward-compatibility. It has no effect on V8.
   int (*CobaltJsGarbageCollectionThresholdInBytes)();
 
   // When specified this value will reduce the cpu memory consumption by
diff --git a/src/cobalt/extension/updater_notification.h b/src/cobalt/extension/updater_notification.h
index 151437f..ce301dc 100644
--- a/src/cobalt/extension/updater_notification.h
+++ b/src/coba