Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: third_party/WebKit/Source/core/fetch/Resource.cpp

Issue 1915833002: Introduce Platform::cacheMetadataInCacheStorage() to store V8 code cache in CacheStorage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add comments in render_process_messages.h Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 23 matching lines...) Expand all
34 #include "core/inspector/InspectorInstrumentation.h" 34 #include "core/inspector/InspectorInstrumentation.h"
35 #include "core/inspector/InstanceCounters.h" 35 #include "core/inspector/InstanceCounters.h"
36 #include "platform/Logging.h" 36 #include "platform/Logging.h"
37 #include "platform/SharedBuffer.h" 37 #include "platform/SharedBuffer.h"
38 #include "platform/TraceEvent.h" 38 #include "platform/TraceEvent.h"
39 #include "platform/network/HTTPParsers.h" 39 #include "platform/network/HTTPParsers.h"
40 #include "platform/weborigin/KURL.h" 40 #include "platform/weborigin/KURL.h"
41 #include "public/platform/Platform.h" 41 #include "public/platform/Platform.h"
42 #include "public/platform/WebProcessMemoryDump.h" 42 #include "public/platform/WebProcessMemoryDump.h"
43 #include "public/platform/WebScheduler.h" 43 #include "public/platform/WebScheduler.h"
44 #include "public/platform/WebSecurityOrigin.h"
44 #include "wtf/CurrentTime.h" 45 #include "wtf/CurrentTime.h"
45 #include "wtf/MathExtras.h" 46 #include "wtf/MathExtras.h"
46 #include "wtf/StdLibExtras.h" 47 #include "wtf/StdLibExtras.h"
47 #include "wtf/Vector.h" 48 #include "wtf/Vector.h"
48 #include "wtf/text/CString.h" 49 #include "wtf/text/CString.h"
49 #include <algorithm> 50 #include <algorithm>
50 51
51 namespace blink { 52 namespace blink {
52 53
53 // These response headers are not copied from a revalidated response to the 54 // These response headers are not copied from a revalidated response to the
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 if (equalIgnoringCase(header, headersToIgnoreAfterRevalidation[i])) 86 if (equalIgnoringCase(header, headersToIgnoreAfterRevalidation[i]))
86 return false; 87 return false;
87 } 88 }
88 for (size_t i = 0; i < WTF_ARRAY_LENGTH(headerPrefixesToIgnoreAfterRevalidat ion); i++) { 89 for (size_t i = 0; i < WTF_ARRAY_LENGTH(headerPrefixesToIgnoreAfterRevalidat ion); i++) {
89 if (header.startsWith(headerPrefixesToIgnoreAfterRevalidation[i], TextCa seInsensitive)) 90 if (header.startsWith(headerPrefixesToIgnoreAfterRevalidation[i], TextCa seInsensitive))
90 return false; 91 return false;
91 } 92 }
92 return true; 93 return true;
93 } 94 }
94 95
95 class Resource::CacheHandler : public CachedMetadataHandler { 96 class Resource::CachedMetadataHandlerImpl : public CachedMetadataHandler {
96 public: 97 public:
97 static CacheHandler* create(Resource* resource) 98 static Resource::CachedMetadataHandlerImpl* create(Resource* resource)
98 { 99 {
99 return new CacheHandler(resource); 100 return new CachedMetadataHandlerImpl(resource);
100 } 101 }
101 ~CacheHandler() override { } 102 ~CachedMetadataHandlerImpl() override {}
102 DECLARE_VIRTUAL_TRACE(); 103 DECLARE_VIRTUAL_TRACE();
103 void setCachedMetadata(unsigned, const char*, size_t, CacheType) override; 104 void setCachedMetadata(unsigned, const char*, size_t, CacheType) override;
104 void clearCachedMetadata(CacheType) override; 105 void clearCachedMetadata(CacheType) override;
105 CachedMetadata* cachedMetadata(unsigned) const override; 106 CachedMetadata* cachedMetadata(unsigned) const override;
106 String encoding() const override; 107 String encoding() const override;
108 // Sets the serialized metadata retrieved from the platform's cache.
109 void setSerializedCachedMetadata(const char*, size_t);
110
111 protected:
112 explicit CachedMetadataHandlerImpl(Resource*);
113 virtual void sendToPlatform();
114 const ResourceResponse& response() const { return m_resource->response(); }
115
116 RefPtr<CachedMetadata> m_cachedMetadata;
107 117
108 private: 118 private:
109 explicit CacheHandler(Resource*);
110 Member<Resource> m_resource; 119 Member<Resource> m_resource;
111 }; 120 };
112 121
113 Resource::CacheHandler::CacheHandler(Resource* resource) 122 Resource::CachedMetadataHandlerImpl::CachedMetadataHandlerImpl(Resource* resourc e)
114 : m_resource(resource) 123 : m_resource(resource)
115 { 124 {
116 } 125 }
117 126
118 DEFINE_TRACE(Resource::CacheHandler) 127 DEFINE_TRACE(Resource::CachedMetadataHandlerImpl)
119 { 128 {
120 visitor->trace(m_resource); 129 visitor->trace(m_resource);
121 CachedMetadataHandler::trace(visitor); 130 CachedMetadataHandler::trace(visitor);
122 } 131 }
123 132
124 void Resource::CacheHandler::setCachedMetadata(unsigned dataTypeID, const char* data, size_t size, CacheType type) 133 void Resource::CachedMetadataHandlerImpl::setCachedMetadata(unsigned dataTypeID, const char* data, size_t size, CachedMetadataHandler::CacheType cacheType)
125 { 134 {
126 m_resource->setCachedMetadata(dataTypeID, data, size, type); 135 // Currently, only one type of cached metadata per resource is supported.
136 // If the need arises for multiple types of metadata per resource this could
137 // be enhanced to store types of metadata in a map.
138 ASSERT(!m_cachedMetadata);
139 m_cachedMetadata = CachedMetadata::create(dataTypeID, data, size);
140 if (cacheType == CachedMetadataHandler::SendToPlatform)
141 sendToPlatform();
127 } 142 }
128 143
129 void Resource::CacheHandler::clearCachedMetadata(CacheType type) 144 void Resource::CachedMetadataHandlerImpl::clearCachedMetadata(CachedMetadataHand ler::CacheType cacheType)
130 { 145 {
131 m_resource->clearCachedMetadata(type); 146 m_cachedMetadata.clear();
147 if (cacheType == CachedMetadataHandler::SendToPlatform)
148 sendToPlatform();
132 } 149 }
133 150
134 CachedMetadata* Resource::CacheHandler::cachedMetadata(unsigned dataTypeID) cons t 151 CachedMetadata* Resource::CachedMetadataHandlerImpl::cachedMetadata(unsigned dat aTypeID) const
135 { 152 {
136 return m_resource->cachedMetadata(dataTypeID); 153 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID)
154 return nullptr;
155 return m_cachedMetadata.get();
137 } 156 }
138 157
139 String Resource::CacheHandler::encoding() const 158 String Resource::CachedMetadataHandlerImpl::encoding() const
140 { 159 {
141 return m_resource->encoding(); 160 return m_resource->encoding();
142 } 161 }
143 162
163 void Resource::CachedMetadataHandlerImpl::setSerializedCachedMetadata(const char * data, size_t size)
164 {
165 // We only expect to receive cached metadata from the platform once.
166 // If this triggers, it indicates an efficiency problem which is most
167 // likely unexpected in code designed to improve performance.
168 ASSERT(!m_cachedMetadata);
169 m_cachedMetadata = CachedMetadata::deserialize(data, size);
170 }
171
172 void Resource::CachedMetadataHandlerImpl::sendToPlatform()
173 {
174 if (m_cachedMetadata) {
175 const Vector<char>& serializedData = m_cachedMetadata->serialize();
176 Platform::current()->cacheMetadata(response().url(), response().response Time(), serializedData.data(), serializedData.size());
177 } else {
178 Platform::current()->cacheMetadata(response().url(), response().response Time(), nullptr, 0);
179 }
180 }
181
182 class Resource::ServiceWorkerResponseCachedMetadataHandler : public Resource::Ca chedMetadataHandlerImpl {
183 public:
184 static Resource::CachedMetadataHandlerImpl* create(Resource* resource, Secur ityOrigin* securityOrigin)
185 {
186 return new ServiceWorkerResponseCachedMetadataHandler(resource, security Origin);
187 }
188 ~ServiceWorkerResponseCachedMetadataHandler() override {}
189 DECLARE_VIRTUAL_TRACE();
190
191 protected:
192 void sendToPlatform() override;
193
194 private:
195 explicit ServiceWorkerResponseCachedMetadataHandler(Resource*, SecurityOrigi n*);
196 String m_cacheStorageCacheName;
197 RefPtr<SecurityOrigin> m_securityOrigin;
198 };
199
200 Resource::ServiceWorkerResponseCachedMetadataHandler::ServiceWorkerResponseCache dMetadataHandler(Resource* resource, SecurityOrigin* securityOrigin)
201 : CachedMetadataHandlerImpl(resource)
202 , m_securityOrigin(securityOrigin)
203 {
204 }
205
206 DEFINE_TRACE(Resource::ServiceWorkerResponseCachedMetadataHandler)
207 {
208 CachedMetadataHandlerImpl::trace(visitor);
209 }
210
211 void Resource::ServiceWorkerResponseCachedMetadataHandler::sendToPlatform()
212 {
213 // We don't support sending the metadata to the platform when the response
214 // was directly fetched via a ServiceWorker
215 // (eg: FetchEvent.respondWith(fetch(FetchEvent.request))) to prevent an
216 // attacker's Service Worker from poisoning the metadata cache of HTTPCache.
217 if (response().cacheStorageCacheName().isNull())
218 return;
219
220 if (m_cachedMetadata) {
221 const Vector<char>& serializedData = m_cachedMetadata->serialize();
222 Platform::current()->cacheMetadataInCacheStorage(response().url(), respo nse().responseTime(), serializedData.data(), serializedData.size(), WebSecurityO rigin(m_securityOrigin), response().cacheStorageCacheName());
223 } else {
224 Platform::current()->cacheMetadataInCacheStorage(response().url(), respo nse().responseTime(), nullptr, 0, WebSecurityOrigin(m_securityOrigin), response( ).cacheStorageCacheName());
225 }
226 }
227
144 class Resource::ResourceCallback final : public GarbageCollectedFinalized<Resour ceCallback> { 228 class Resource::ResourceCallback final : public GarbageCollectedFinalized<Resour ceCallback> {
145 public: 229 public:
146 static ResourceCallback& callbackHandler(); 230 static ResourceCallback& callbackHandler();
147 DECLARE_TRACE(); 231 DECLARE_TRACE();
148 void schedule(Resource*); 232 void schedule(Resource*);
149 void cancel(Resource*); 233 void cancel(Resource*);
150 bool isScheduled(Resource*) const; 234 bool isScheduled(Resource*) const;
151 private: 235 private:
152 ResourceCallback(); 236 ResourceCallback();
153 237
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 , m_type(type) 308 , m_type(type)
225 , m_status(NotStarted) 309 , m_status(NotStarted)
226 , m_needsSynchronousCacheHit(false) 310 , m_needsSynchronousCacheHit(false)
227 , m_linkPreload(false) 311 , m_linkPreload(false)
228 { 312 {
229 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. 313 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum.
230 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); 314 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter);
231 315
232 // Currently we support the metadata caching only for HTTP family. 316 // Currently we support the metadata caching only for HTTP family.
233 if (m_resourceRequest.url().protocolIsInHTTPFamily()) 317 if (m_resourceRequest.url().protocolIsInHTTPFamily())
234 m_cacheHandler = CacheHandler::create(this); 318 m_cacheHandler = CachedMetadataHandlerImpl::create(this);
235 } 319 }
236 320
237 Resource::~Resource() 321 Resource::~Resource()
238 { 322 {
239 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); 323 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter);
240 } 324 }
241 325
242 void Resource::removedFromMemoryCache() 326 void Resource::removedFromMemoryCache()
243 { 327 {
244 InspectorInstrumentation::removedResourceFromMemoryCache(this); 328 InspectorInstrumentation::removedResourceFromMemoryCache(this);
(...skipping 13 matching lines...) Expand all
258 return; 342 return;
259 343
260 RELEASE_ASSERT(!m_loader); 344 RELEASE_ASSERT(!m_loader);
261 ASSERT(stillNeedsLoad()); 345 ASSERT(stillNeedsLoad());
262 m_status = Pending; 346 m_status = Pending;
263 347
264 ResourceRequest& request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest); 348 ResourceRequest& request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest);
265 KURL url = request.url(); 349 KURL url = request.url();
266 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC redentials); 350 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC redentials);
267 351
352 m_fetcherSecurityOrigin = fetcher->context().getSecurityOrigin();
268 m_loader = ResourceLoader::create(fetcher, this); 353 m_loader = ResourceLoader::create(fetcher, this);
269 m_loader->start(request); 354 m_loader->start(request);
270 // If the request reference is null (i.e., a synchronous revalidation will 355 // If the request reference is null (i.e., a synchronous revalidation will
271 // null the request), don't make the request non-null by setting the url. 356 // null the request), don't make the request non-null by setting the url.
272 if (!request.isNull()) 357 if (!request.isNull())
273 request.setURL(url); 358 request.setURL(url);
274 } 359 }
275 360
276 void Resource::checkNotify() 361 void Resource::checkNotify()
277 { 362 {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 m_revalidatingRequest = request; 552 m_revalidatingRequest = request;
468 m_status = NotStarted; 553 m_status = NotStarted;
469 } 554 }
470 555
471 void Resource::willFollowRedirect(ResourceRequest& newRequest, const ResourceRes ponse& redirectResponse) 556 void Resource::willFollowRedirect(ResourceRequest& newRequest, const ResourceRes ponse& redirectResponse)
472 { 557 {
473 newRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStor edCredentials); 558 newRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStor edCredentials);
474 m_redirectChain.append(RedirectPair(newRequest, redirectResponse)); 559 m_redirectChain.append(RedirectPair(newRequest, redirectResponse));
475 } 560 }
476 561
562 void Resource::setResponse(const ResourceResponse& response)
563 {
564 m_response = response;
565 if (m_response.wasFetchedViaServiceWorker())
566 m_cacheHandler = ServiceWorkerResponseCachedMetadataHandler::create(this , m_fetcherSecurityOrigin.get());
567 }
568
477 bool Resource::unlock() 569 bool Resource::unlock()
478 { 570 {
479 if (!m_data) 571 if (!m_data)
480 return false; 572 return false;
481 573
482 if (!m_data->isLocked()) 574 if (!m_data->isLocked())
483 return true; 575 return true;
484 576
485 if (!memoryCache()->contains(this) || hasClientsOrObservers() || !m_revalida tingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock()) 577 if (!memoryCache()->contains(this) || hasClientsOrObservers() || !m_revalida tingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock())
486 return false; 578 return false;
(...skipping 14 matching lines...) Expand all
501 revalidationFailed(); 593 revalidationFailed();
502 } 594 }
503 setResponse(response); 595 setResponse(response);
504 String encoding = response.textEncodingName(); 596 String encoding = response.textEncodingName();
505 if (!encoding.isNull()) 597 if (!encoding.isNull())
506 setEncoding(encoding); 598 setEncoding(encoding);
507 } 599 }
508 600
509 void Resource::setSerializedCachedMetadata(const char* data, size_t size) 601 void Resource::setSerializedCachedMetadata(const char* data, size_t size)
510 { 602 {
511 // We only expect to receive cached metadata from the platform once.
512 // If this triggers, it indicates an efficiency problem which is most
513 // likely unexpected in code designed to improve performance.
514 ASSERT(!m_cachedMetadata);
515 ASSERT(m_revalidatingRequest.isNull()); 603 ASSERT(m_revalidatingRequest.isNull());
516 604 ASSERT(!m_response.isNull());
517 m_cachedMetadata = CachedMetadata::deserialize(data, size); 605 if (m_cacheHandler)
606 m_cacheHandler->setSerializedCachedMetadata(data, size);
518 } 607 }
519 608
520 CachedMetadataHandler* Resource::cacheHandler() 609 CachedMetadataHandler* Resource::cacheHandler()
521 { 610 {
522 return m_cacheHandler.get(); 611 return m_cacheHandler.get();
523 } 612 }
524 613
525 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType)
526 {
527 // Currently, only one type of cached metadata per resource is supported.
528 // If the need arises for multiple types of metadata per resource this could
529 // be enhanced to store types of metadata in a map.
530 ASSERT(!m_cachedMetadata);
531
532 m_cachedMetadata = CachedMetadata::create(dataTypeID, data, size);
533
534 // We don't support sending the metadata to the platform when the response
535 // was fetched via a ServiceWorker to prevent an attacker's Service Worker
536 // from poisoning the metadata cache.
537 // FIXME: Support sending the metadata even if the response was fetched via
538 // a ServiceWorker. https://crbug.com/448706
539 if (cacheType == CachedMetadataHandler::SendToPlatform && !m_response.wasFet chedViaServiceWorker()) {
540 const Vector<char>& serializedData = m_cachedMetadata->serialize();
541 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), serializedData.data(), serializedData.size());
542 }
543 }
544
545 void Resource::clearCachedMetadata(CachedMetadataHandler::CacheType cacheType)
546 {
547 m_cachedMetadata.clear();
548
549 if (cacheType == CachedMetadataHandler::SendToPlatform)
550 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0);
551 }
552 614
553 String Resource::reasonNotDeletable() const 615 String Resource::reasonNotDeletable() const
554 { 616 {
555 StringBuilder builder; 617 StringBuilder builder;
556 if (hasClientsOrObservers()) { 618 if (hasClientsOrObservers()) {
557 builder.append("hasClients("); 619 builder.append("hasClients(");
558 builder.appendNumber(m_clients.size()); 620 builder.appendNumber(m_clients.size());
559 if (!m_clientsAwaitingCallback.isEmpty()) { 621 if (!m_clientsAwaitingCallback.isEmpty()) {
560 builder.append(", AwaitingCallback="); 622 builder.append(", AwaitingCallback=");
561 builder.appendNumber(m_clientsAwaitingCallback.size()); 623 builder.appendNumber(m_clientsAwaitingCallback.size());
(...skipping 17 matching lines...) Expand all
579 builder.append(")"); 641 builder.append(")");
580 } 642 }
581 if (memoryCache()->contains(this)) { 643 if (memoryCache()->contains(this)) {
582 if (!builder.isEmpty()) 644 if (!builder.isEmpty())
583 builder.append(' '); 645 builder.append(' ');
584 builder.append("in_memory_cache"); 646 builder.append("in_memory_cache");
585 } 647 }
586 return builder.toString(); 648 return builder.toString();
587 } 649 }
588 650
589 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
590 {
591 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID)
592 return nullptr;
593 return m_cachedMetadata.get();
594 }
595
596 void Resource::clearLoader() 651 void Resource::clearLoader()
597 { 652 {
598 m_loader = nullptr; 653 m_loader = nullptr;
599 } 654 }
600 655
601 void Resource::didAddClient(ResourceClient* c) 656 void Resource::didAddClient(ResourceClient* c)
602 { 657 {
603 if (isLoaded()) { 658 if (isLoaded()) {
604 c->notifyFinished(this); 659 c->notifyFinished(this);
605 if (m_clients.contains(c)) { 660 if (m_clients.contains(c)) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 m_resourceRequest = m_revalidatingRequest; 926 m_resourceRequest = m_revalidatingRequest;
872 m_revalidatingRequest = ResourceRequest(); 927 m_revalidatingRequest = ResourceRequest();
873 } 928 }
874 929
875 void Resource::revalidationFailed() 930 void Resource::revalidationFailed()
876 { 931 {
877 m_resourceRequest = m_revalidatingRequest; 932 m_resourceRequest = m_revalidatingRequest;
878 m_revalidatingRequest = ResourceRequest(); 933 m_revalidatingRequest = ResourceRequest();
879 m_redirectChain.clear(); 934 m_redirectChain.clear();
880 m_data.clear(); 935 m_data.clear();
881 m_cachedMetadata.clear(); 936 m_cacheHandler.clear();
882 destroyDecodedDataForFailedRevalidation(); 937 destroyDecodedDataForFailedRevalidation();
883 } 938 }
884 939
885 bool Resource::canReuseRedirectChain() 940 bool Resource::canReuseRedirectChain()
886 { 941 {
887 for (auto& redirect : m_redirectChain) { 942 for (auto& redirect : m_redirectChain) {
888 if (!canUseResponse(redirect.m_redirectResponse, m_responseTimestamp)) 943 if (!canUseResponse(redirect.m_redirectResponse, m_responseTimestamp))
889 return false; 944 return false;
890 if (redirect.m_request.cacheControlContainsNoCache() || redirect.m_reque st.cacheControlContainsNoStore()) 945 if (redirect.m_request.cacheControlContainsNoCache() || redirect.m_reque st.cacheControlContainsNoStore())
891 return false; 946 return false;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 case Resource::Media: 1132 case Resource::Media:
1078 return "Media"; 1133 return "Media";
1079 case Resource::Manifest: 1134 case Resource::Manifest:
1080 return "Manifest"; 1135 return "Manifest";
1081 } 1136 }
1082 ASSERT_NOT_REACHED(); 1137 ASSERT_NOT_REACHED();
1083 return "Unknown"; 1138 return "Unknown";
1084 } 1139 }
1085 1140
1086 } // namespace blink 1141 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698