the Chromium logo

The Chromium Projects

//base Newsletter, 2022Q3 Edition

What is this?

The Chromium //base code contains foundational building blocks for the project. It evolves over time to meet the project's changing needs. This periodic newsletter highlights some of the changes Chromium developers should be aware of.

New and shiny

base::expected<typename T, typename E>

A new vocabulary type based on the C++23 proposal that allows functions to return either an expected value of type T on success or an error value of type E on failure, e.g. instead of writing:

// Returns a base::Value::Dict on success, or absl::nullopt on failure. `error`
// will be populated with a diagnostic message on failure.
absl::optional<base::Value::Dict> ParseMyFormat(base::StringPiece input,
                                                std::string& error);

Simply write this instead:

// Returns the parsed base::Value::Dict on success, or a string with a
// diagnostic message on failure.
base::expected<base::Value::Dict, std::string> ParseMyFormat(
    base::StringPiece input);

Returning a success value is simple:

if (auto* dict = parsed_value.GetIfDict()) {
  return std::move(*dict);
}

While returning an error value required using the base::unexpected hint:

return base::unexpected(error_message);

Callers can use has_value() to check for success, and then use value(), operator*, or operator-> to access the success value. On error, callers can use error() instead to access the error value.

One notable divergence from the proposed C++23 library feature is the lack of a bool operator (explicit or otherwise).

New helpers in base/test/metrics/histogram_tester.h

Testing is an important part of Chromium. Even code that records metrics should have test coverage to help ensure the correctness of the metrics. To help support metrics testing, crrev.com/998514 and crrev.com/1002653 changed struct base::Bucket to accept enums, and added 4 new gMock matchers:

Now it is possible to write more concise test expectations when testing metrics.

base::ScopedBoostPriority

Chromium's architecture involves multiple processes and multiple threads. Giving threads the appropriate priority can greatly improve performance, but changing a thread's priority in a safe manner in cross-platform code can be tricky. To avoid subtle bugs, crrev.com/1013320 added base::ScopedBoostPriority to make it easier to boost a thread's priority in a controlled manner, without having to worry about the complications involved in restoring the original priority. Please consider using this scoper instead of calling base::PlatformThread::SetCurrentThreadType() directly.

Moreover, //base contains numerous scoper classes to make life easier for Chromium developers. Check out these examples.

Project updates

Standalone PartitionAlloc

The Chrome Memory Team is preparing to bring the benefits of PartitionAlloc to Chrome-external projects! Our first targets are PDFium (which uses an older copy of PA today), ARCVM, and d8. The goal here is to allow external clients to transparently use PartitionAlloc as their allocator of choice with a simple DEPS roll.

We've already completed most of the work of breaking dependencies on //base, which almost enables us to lift-and-shift the codebase as a single unit. More work is yet to come on doing the same for //build and other Chrome-isms. The team is currently working on assuming control of the shim in //base/allocator, which would allow us to provide the functional equivalent of PartitionAlloc-Everywhere for external clients.

base::Value API refactoring

The commonly used base::Value class has been refactoring its APIs for the last 6 years to better take advantage of modern C++ features. The original v1 proposal had some pain points that made adoption difficult. The v2 proposal addressed those problems and migration to the v2 APIs has been making lots of progress, with many deprecated APIs getting removed in the past year. Please consider helping with migration and take one of the bugs blocking the meta bug.

Issues with the v1 proposal that lead to the v2 proposal:

Open issues with the refactoring:

Reminders

How to use raw_ptr appropriately

The MiraclePtr project seeks to improve memory safety in Chromium. As part of this work, Chromium now uses the raw_ptr smart pointer class in many places. Being relatively new, here is a quick summary on how to use it appropriately:

See base/memory/raw_ptr.md for more details.

Use base::BindLambdaForTesting() to simplify tests

When dealing with callbacks in tests, oftentimes it can be much easier to use base::BindLambdaForTesting() instead of base::BindRepeating()/BindOnce(). Example CL.

Bye bye

base::PostTask() and friends in base/task/post_task.h

base::PostTask() was the original way of posting to the “thread pool” (then named base::TaskScheduler). It was then enhanced to allow base::TaskTraits to specify BrowserThreads as a destination. base::ThreadPool() was later added as a trait to force explicitly mentioning the destination. That was deemed overly complicated and was moved to API-as-a-destination in Task APIs v3. Namely, base::ThreadPool::* and content::Get(UI|IO)ThreadTaskRunner().

base/task/post_task.h is gone as of crrev.com/998343. However, on Android, the Java side of PostTask() still needs to go through this migration and is thus the only (internal) caller remaining of the old traits-as-destination format which allows //base to post to //content. //content Java browser thread APIs will need to be added to fully finalize this API-as-a-destination migration and cleanup the internal hooks for it.

base::CharTraits in base/strings/char_traits.h

This was a constexpr version of std::char_traits from the <string> header. std::char_traits became constexpr in C++17, so existing uses were migrated to std::char_traits and the //base version was removed in crrev.com/993996.