 Thanks everyone. My name is John Abdel Malik. I've been on Chrome for about 12 years here to talk about the internals of Chrome. My kind of purpose of this talk is to give a background of why you see the various layers in the code. Why is all this complexity there? A colleague was able to figure out the number of lines of code. And when we launched, there was about two and a half million lines of code. Today it's 25 million, so it's a huge increase in complexity. And you'd be looking through it for the engineers and be like, why is it like this? Why are there so many layers? So I'm hoping to give it back kind of why that's the case. So I'm going to start by giving an overview of Chrome's unique architecture and why it was built to support the four S's. You've heard about these, I'm guessing, already multiple times, right? Speed, security, stability, and simplicity. You're going to hear about them many times, right? If it feels repetitive, it's because really they're central to everything that we do. Every time we're trying to figure out how something should be implemented, what the user interface should look like, these are kind of the principles that drive our thinking. I'm not going to talk about the past, current, and future improvements we've made to the code base and architecture of Chrome. So what did things look like before Chrome? Everything ran in the same process. The networking, the UI, the rendering engine, the plugins, image decoding, and so on. And actually most of these things ran on the same thread. And this was obviously not an ideal, right? Because if one tab stopped working or crashed, it would take down all the other tabs in the browser itself. And if you remember those days, that's like when you would be writing a big email and then your browser would crash and you'd lose it and you have to start all over again, right? So this kind of was not great. But of course a lot of apps were written that way at the time, right? This is before most users had like multi-core CPUs and so on. But how did Chrome look like when we launched? So this is kind of what it looked like, you know, in Chrome 1.0. There were multiple processes. Each of these is denoted by like a box. Some of them are sandbox. I'll talk more about that later and that's the red line. They talk to each other through these dotted lines, which is IPC. This is a huge improvement from the status quo. We moved the code that we control and which operates on untrusted data from the Internet into these processes that we kind of limit kind of a damage that can do your system. There were multiple of these processes. So if one tab went down, it wouldn't take down the other tabs. And then there were plugins that weren't under our control. We still have to run multiple processes for these on Sandboxed. This is a different way of looking at our multi-process architecture to see which parts or which processes draw which parts of the UI. So the tab strip at the top is drawn by the browser process, the main process. The HTML is rendered by the render processes and the plugin processes were used to draw like videos like flash. So why did we do a multi-process architecture? Like everything in engineering, there's a trade-off. So multiple processes, that's going to have some memory overhead. There's some complexity in being able to pass all this data back and forth efficiently. There's obviously going to be some performance overhead in some cases. And the main reason is you just couldn't write perfect code. There's always going to be bugs in the code that we write and in all the various third-party libraries that we consume. And so because of these bugs, you could have security issues. Yeah, so there could be security issues. Bugs could be used for exploits to be able to escape the Sandbox. You could have speed problems if there's buggy code that has bad algorithm or there's poorly written HTML pages or JavaScript in your site. Not even code that you control. Things that you pulled in through various libraries, that could cause the browser to be hung. Another reason is stability. We want to make sure that if a tab crashes, it doesn't break down the whole browser or other tabs. So multi-process is sometimes like a silver bullet for all this stuff. It helps in security and stability and speed. I mentioned IPC earlier. That stands for inter-process communication. And that's how all these processes talk to each other. Generally, we use message passing and for any large data we use shared memory. This is usually between processes of different privileges. So every time you cross this IPC layer, you're going to have to go through a security review just to make sure that there aren't any ways for less privileged process to take over a more privileged process. Usually, this is asynchronous communication. There are ways of doing synchronous communication, but we heavily discourage that because of performance overhead. Sandboxing is something I mentioned earlier. Since untrusted data can be used to exploit bugs and execute code on your system, we need to guard against that. In the beginning, the rendering engines were pretty simple, right? Because it was just rendering. But as we move to web apps and more complicated browser engines or rendering engines to support that, there's a lot of extra vectors to exploit your system. So we move all this code that operates on untrusted data into processes that are sandboxed, which means it doesn't have access to your file system to make operating system calls and so on. And then this improves the security. The exact mechanism to do this is very platform-specific. So we've got sandboxing code that's specific on Android and on Mac and Windows. And we often work with OS vendors to kind of add new capabilities to further lock down these sandboxes. And sometimes there are also multiple levels of sandboxing depending on the process type. So the main kind of thing that runs all your web content is a render process. This is where you handle data from the web and things like parsing of the HTML, doing layout, executing JavaScript, decoding images and videos and audio and so on. It's completely sandboxed. So this is the most lockdown process in the browser. Another process type that we launched was with plugins. So when we launched it was a secret project so we couldn't kind of tell anyone else we were working on it. And this means that at launch, we had to support all these plugins that users or the web content depended on at that time, right? Things like Flash and Java and Adobe Reader. If you didn't support them, then a lot of the web content wouldn't render. So we figured out how to get this working in multi-processed, which was never how they were intended to run. But at the same time, we had to make them run on sandbox because this is third-party code that is kind of written with an assumption that has full access to your machine. Lastly, the browser process is kind of the dissenter coordinator. It owns a browser state like your profile data and your settings. It draws like the UI around the content area, and it handles networking. And since it's the most trusted, it can't trust all the other processes because it could be trying to lie to it. Generally, in most processes, there's at least one main thread and an IPC thread. There are also many other threads in the browser process for things like databases or just helper threads. So you can offload expensive work from the main threads. The main threads in the browser process are the UI thread, which is the main thread. That's where all the user interface code runs along the logic. Then there's a very poorly named thread that's called the IO thread. But you can kind of, every time you see IO, just think non-blocking IO because that's never where we'll do things like disk access or any expensive operations. And so kind of what I talked about before is how we launched. And how does Chrome look like today? We've done a lot of improvements. You can see we added a bunch of more process types. There's a GPU, which is partly sandboxed. The utility process, extension process. Plugins have now a red border, which means you're sandboxed. And the render, instead of running WebKit, it's this new thing, which is Blink that we forked from WebKit. I'm going to talk more about these in the next slides. So what is the GPU process? Well, one thing we observed was that kind of machines with powerful GPUs are becoming widespread. At the same time, there were new platform features like WebGL, which to render in our old architecture means we'd have to do expensive feedback. So that wasn't good for performance. So this was a very large project to offload compositing and scrolling onto the GPU hardware. Improves performance and power consumption. And also, to do this properly, there were a lot of buggy GPU drivers, so we couldn't just run this in the browser process because then these bugs in the drivers could be used to exploit or cause crashes. So this also runs in a separate process. That's partially sandboxed. Utility process is a new process that we use for short-lived work. And as a browser, gain more capabilities like extensions or there's like JSON headers that come in various API calls and we didn't trust our JSON parser. So we wanted to run that in a separate process that we could sandbox, take the data, kind of do some operation on it, return the response, and then kind of kill itself. So that's that process. And then extensions. So when we launched, we didn't have extension support. We're just trying to scope down the problem, the massive problem of launching a new browser. But we always knew that we needed extension support because there's so many things that we'd want to do in a browser that different users would want and we couldn't possibly complement all of that ourselves. So extensions allow users to customize it without loading the product for everyone. But at the same time, we wanted to learn from issues we saw in other extension implementations. We didn't want a bad extension to be able to store down your browser or, you know, the tab. We didn't want a bad extension to be able to have full access to the JavaScript state. And we also didn't want you to have to restart your browser every time you added or removed an extension. So extension kind of processes allowed us to have a lot of this separation in terms of kind of restartability and performance and security. The next thing is PEPRA plugins. So kind of as Chrome was a new browser, it had different code base in a lot of other browsers and also had a sandbox. But our kind of weak point was NPPI plugins. And it turned out, right, having the same binary being loaded in all different browsers was a very convenient way to write, you know, cross browser exploits. And we were getting a lot of the issues we were having were with kind of code that we didn't control from third parties. So this was a multi-year effort to be able to create a new API to replace, you know, the 20-year-old plus or the 15-year-old plus API and NPPI with something much better that could be sandboxed. We ported the flash code base and we worked closely with Adobe to get the code and make it be able to run in a sandbox process. And then for PDF, we created a new plugin based on, you know, PDF rendering engine that we licensed in the third party. This was like a huge improvement for security. Another large kind of rearchitecture of Chrome happened with the Chrome content split. Originally, we started this to improve the code layering and testability of our code. We split the browser, like the product part of the browser, which is Chrome, from the platform. And the platform we kind of defined was that the code to be able to run the sandbox multi-process or platform engine. And so we kept the product code in source Chrome and created a new directory called source content. And that's where we put the low-level kind of code. The higher-level code were things like bookmarks, extensions, password manager, autofill, and that stayed in source Chrome. And everything else kind of moved to content. And the neat thing about this is originally we did this just as a way to improve our own developer productivity. But then there were a lot of external and internal products that came about as a result. So we were able to run Android WebView built on top of content. We were able to ship Chromecast and Google Home on top of this platform. And then outside there are things like Electron that were built on top of this as well. Another large kind of multi-year re-architecture was Componization. And that came about because we wanted to develop a browser in iOS. But in iOS, you have to use the browser engine that's provided by the system. And we couldn't use Blink. So all the code that we had for things like password manager and autofill depended on hooks inside Blink. So we separated that from source Chrome into source components. And we isolated the parts of top of Blink so that we could replace it with parts that work on iOS. And that's kind of why you'll see a lot of these layered components and source components. Then another massive effort, a multi-year effort, was to improve security. So originally Chrome Sandbox was great because a lot of your files were on the system. And so if you could prevent malicious content, let's say, from reading your documents directory, that was a big improvement. But as more of your data moves online or moved online, actually I don't personally care about an exploit reaching my files as to what I really care is they don't have access to my drive files and photos and so on. But if everything's running in one render process, you couldn't really like a page could just lie and say, okay, I've got a Google iFrame now give me all the Google cookies and so on to be able to pass these cookies to other sites or be able to kind of make requests to other servers and feed them all your data. And so this was a massive effort but to split the page. So instead of just running each tab in a separate process, be able to run each tab in different processes depending on the origin. And the neat thing is, this was started because we had people like Charlie and Nazco kind of could see that this was a very nice security improvement. But before it was even launched there was these new processor bugs that came about like I think last year or two years ago. And so it was like perfect timing that we could ship this and work around these security bugs and processors. So it was a big improvement and biggest for architecture in Chrome since we launched. Another new thing that we did is Mojo which is our new IPC system. Ken and Oksana will talk about this more later today, later in the afternoon but I just wanted to give you a high level overview. This is IDL based which was different than our old system. It solves a lot of the issues we had with our kind of macro based data from handles like shared memory. They had to have special code. You had to have special code depending on where the caller and the callee run and if you wanted to move something to a different process you'd have to kind of have different code tasks. We couldn't send IPCs directly from Blink so you had to have all these kind of busy work layers of just converting one type to another. So that's kind of the issues that we faced. We had to have a lot of different types of code that were automatically and we have a few kind of different primitives that are used as part of Mojo. They're message pipes which are bi-directional. The nice thing about them is they're really, really cheap so there are no like OS primitives created for each one. They're all kind of one together. There's also shared buffers and diagnostics so you could have any of these objects use them on one thread, pass them on to another thread or to a different process and everything works automatically. You can kind of use them for a little bit and then pass it off to someone else who can then reuse them so it's really powerful and we'll be able to use a lot of that to simplify the code and I'll talk more about that in the next slides. So what does the future Chrome do to so many new platforms and products that you could never have kind of forecast when you started writing the code? So kind of step back and try to figure out, okay, how do we really want to architect the code so that it's more easy to reuse? So when we have new use cases, it's headless or if it's running without all the other code, if it wants to run just a simplified version, how do you make that possible? The solution to this was to turn your code into microservices. Microservices are kind of have a well-defined API, they're reusable so you can kind of take pieces and run them in different scenarios. Services are decoupled from each other so you could run a subset of them at a time and it's also built in a layered way so you could kind of build like a file system service and then take that and reuse it to build a level DB as well. Some of the benefits we wanted to achieve from this is speed. We wanted to have fewer conversions so you could run the subsystems closer to the call sites. We wanted to be able to split code into services that could be sandbox and that improves stability because if it crashes it doesn't take down the browser, it also improves security because we could sandbox that new process type. And then also simplicity and kind of overriding simplicity that word because usually we use that for the user interface but here I'm talking about simplicity from the developer's point of view. If you could reduce boundaries if you could have way fewer methods of doing the same thing instead of doing it differently in the browser process and the render process and the utility process like maybe it should be the exact same API that you use from everywhere. And this is like a to go back to my earlier diagrams with the process models. This is one way that we could run the browser with this with microservices. So you could see we moved networking and storage into different processes and their sandbox which is a big improvement. There's also like a UI service or device service and that's if you have a lot of memory so you don't may not care about the small overhead of each process. But then on mobile when you have kind of much more constrained devices with a flip with a one line if statement you can suddenly decide okay I'm going to run these services together in the same process and that's for example a code that's something that we do already today. Another benefit is you can just say well I'm not going to run all the browser code let's say the user closed the browser but there's you know pending download instead of keeping the browser open or it could be killed by the user or the system because we're not resources we can just run a small subset just the networking code just the storage code and that would be like kind of a lot more likely to run to completion. So a lot of that is kind of benefits that we get from module gives us so much flexibility that we can kind of do these new use cases. And then lastly I'm going to just go over a quick overview of the directory structure to kind of tie all the previous things I talked about. So base is where you're going to find like the file, the string utilities and so on Chrome is our product on desktop and mobile other than IOS that is in source IOS. Components is where you move the layered components that are shared with desktop and IOS and content is like our low-level platform engine. Net is our low-level networking library services where microservices go and then Blink is our rendering engine UI is where you put like the frameworks we use to create the browser UI. These are things outside of the content area and V8 is our JavaScript engine.