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

Side by Side Diff: third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp

Issue 2834733003: Separate preaload matching from MemoryCache (Closed)
Patch Set: fix Created 3 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) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
6 rights reserved. 6 rights reserved.
7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
8 8
9 This library is free software; you can redistribute it and/or 9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public 10 modify it under the terms of the GNU Library General Public
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { 475 if (params.IsSpeculativePreload() || params.IsLinkPreload()) {
476 DEFINE_RESOURCE_HISTOGRAM("Preload."); 476 DEFINE_RESOURCE_HISTOGRAM("Preload.");
477 } else { 477 } else {
478 DEFINE_RESOURCE_HISTOGRAM(""); 478 DEFINE_RESOURCE_HISTOGRAM("");
479 } 479 }
480 480
481 // Aims to count Resource only referenced from MemoryCache (i.e. what would be 481 // Aims to count Resource only referenced from MemoryCache (i.e. what would be
482 // dead if MemoryCache holds weak references to Resource). Currently we check 482 // dead if MemoryCache holds weak references to Resource). Currently we check
483 // references to Resource from ResourceClient and |m_preloads| only, because 483 // references to Resource from ResourceClient and |m_preloads| only, because
484 // they are major sources of references. 484 // they are major sources of references.
485 if (resource && !resource->IsAlive() && !preloads_.Contains(resource)) { 485 if (resource && !resource->IsAlive() && !ContainsAsPreload(resource)) {
486 DEFINE_RESOURCE_HISTOGRAM("Dead."); 486 DEFINE_RESOURCE_HISTOGRAM("Dead.");
487 } 487 }
488 } 488 }
489 489
490 bool ResourceFetcher::ContainsAsPreload(Resource* resource) const {
491 auto it = preloads_.Find(PreloadKey(resource->Url(), resource->GetType()));
492 return it != preloads_.end() && it->value == resource;
493 }
494
495 void ResourceFetcher::RemovePreload(Resource* resource) {
496 auto it = preloads_.Find(PreloadKey(resource->Url(), resource->GetType()));
497 if (it == preloads_.end())
498 return;
499 if (it->value == resource) {
500 resource->DecreasePreloadCount();
501 preloads_.erase(it);
502 }
503 }
504
490 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( 505 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest(
491 FetchParameters& params, 506 FetchParameters& params,
492 const ResourceFactory& factory, 507 const ResourceFactory& factory,
493 const SubstituteData& substitute_data, 508 const SubstituteData& substitute_data,
494 unsigned long identifier, 509 unsigned long identifier,
495 ResourceRequestBlockedReason& blocked_reason) { 510 ResourceRequestBlockedReason& blocked_reason) {
496 ResourceRequest& resource_request = params.MutableResourceRequest(); 511 ResourceRequest& resource_request = params.MutableResourceRequest();
497 512
498 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || 513 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously ||
499 factory.GetType() == Resource::kRaw || 514 factory.GetType() == Resource::kRaw ||
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; 595 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_;
581 if (is_static_data) { 596 if (is_static_data) {
582 resource = ResourceForStaticData(params, factory, substitute_data); 597 resource = ResourceForStaticData(params, factory, substitute_data);
583 // Abort the request if the archive doesn't contain the resource, except in 598 // Abort the request if the archive doesn't contain the resource, except in
584 // the case of data URLs which might have resources such as fonts that need 599 // the case of data URLs which might have resources such as fonts that need
585 // to be decoded only on demand. These data URLs are allowed to be 600 // to be decoded only on demand. These data URLs are allowed to be
586 // processed using the normal ResourceFetcher machinery. 601 // processed using the normal ResourceFetcher machinery.
587 if (!resource && !is_data_url && archive_) 602 if (!resource && !is_data_url && archive_)
588 return nullptr; 603 return nullptr;
589 } 604 }
605 RevalidationPolicy policy = kLoad;
606 bool preload_found = false;
590 if (!resource) { 607 if (!resource) {
591 resource = 608 resource = MatchPreload(params, factory.GetType());
592 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); 609 if (resource) {
610 preload_found = true;
611 policy = kUse;
612 // If |param| is for a blocking resource and a preloaded resource is
613 // found, we may need to make it block the onload event.
614 MakePreloadedResourceBlockOnloadIfNeeded(resource, params);
615 }
593 } 616 }
617 if (!preload_found) {
618 if (!resource) {
619 resource =
620 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier());
621 }
594 622
595 // If we got a preloaded resource from the cache for a non-preload request, 623 policy = DetermineRevalidationPolicy(factory.GetType(), params, resource,
596 // we may need to make it block the onload event. 624 is_static_data);
597 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); 625 TRACE_EVENT_INSTANT1(
598 626 "blink", "ResourceFetcher::determineRevalidationPolicy",
599 const RevalidationPolicy policy = DetermineRevalidationPolicy( 627 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy);
600 factory.GetType(), params, resource, is_static_data); 628 }
601 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy",
602 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy);
603 629
604 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); 630 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data);
605 631
606 switch (policy) { 632 switch (policy) {
607 case kReload: 633 case kReload:
608 GetMemoryCache()->Remove(resource); 634 GetMemoryCache()->Remove(resource);
609 // Fall through 635 // Fall through
610 case kLoad: 636 case kLoad:
611 resource = CreateResourceForLoading(params, params.Charset(), factory); 637 resource = CreateResourceForLoading(params, params.Charset(), factory);
612 break; 638 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // If only the fragment identifiers differ, it is the same resource. 671 // If only the fragment identifiers differ, it is the same resource.
646 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); 672 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url()));
647 RequestLoadStarted(identifier, resource, params, policy, is_static_data); 673 RequestLoadStarted(identifier, resource, params, policy, is_static_data);
648 document_resources_.Set( 674 document_resources_.Set(
649 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); 675 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource);
650 676
651 // Returns with an existing resource if the resource does not need to start 677 // Returns with an existing resource if the resource does not need to start
652 // loading immediately. If revalidation policy was determined as |Revalidate|, 678 // loading immediately. If revalidation policy was determined as |Revalidate|,
653 // the resource was already initialized for the revalidation here, but won't 679 // the resource was already initialized for the revalidation here, but won't
654 // start loading. 680 // start loading.
655 if (!ResourceNeedsLoad(resource, params, policy)) 681 if (!ResourceNeedsLoad(resource, params, policy)) {
682 if (policy != kUse)
683 InsertAsPreloadIfNecessary(resource, params, factory.GetType());
656 return resource; 684 return resource;
685 }
657 686
658 if (!StartLoad(resource)) 687 if (!StartLoad(resource))
659 return nullptr; 688 return nullptr;
689
690 if (policy != kUse)
691 InsertAsPreloadIfNecessary(resource, params, factory.GetType());
660 scoped_resource_load_tracker.resourceLoadContinuesBeyondScope(); 692 scoped_resource_load_tracker.resourceLoadContinuesBeyondScope();
661 693
662 DCHECK(!resource->ErrorOccurred() || 694 DCHECK(!resource->ErrorOccurred() ||
663 params.Options().synchronous_policy == kRequestSynchronously); 695 params.Options().synchronous_policy == kRequestSynchronously);
664 return resource; 696 return resource;
665 } 697 }
666 698
667 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { 699 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) {
668 DCHECK_EQ(timer, &resource_timing_report_timer_); 700 DCHECK_EQ(timer, &resource_timing_report_timer_);
669 Vector<RefPtr<ResourceTimingInfo>> timing_reports; 701 Vector<RefPtr<ResourceTimingInfo>> timing_reports;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 if (it != resource_timing_info_map_.end()) { 834 if (it != resource_timing_info_map_.end()) {
803 it->value->AddRedirect(redirect_response, cross_origin); 835 it->value->AddRedirect(redirect_response, cross_origin);
804 } 836 }
805 837
806 if (resource->GetType() == Resource::kMainResource) { 838 if (resource->GetType() == Resource::kMainResource) {
807 DCHECK(navigation_timing_info_); 839 DCHECK(navigation_timing_info_);
808 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); 840 navigation_timing_info_->AddRedirect(redirect_response, cross_origin);
809 } 841 }
810 } 842 }
811 843
812 ResourceFetcher::RevalidationPolicy 844 Resource* ResourceFetcher::MatchPreload(const FetchParameters& params,
813 ResourceFetcher::DetermineRevalidationPolicy( 845 Resource::Type type) {
814 Resource::Type type, 846 auto it = preloads_.Find(PreloadKey(params.Url(), type));
815 const FetchParameters& fetch_params, 847 if (it == preloads_.end())
816 Resource* existing_resource, 848 return nullptr;
817 bool is_static_data) const {
818 const ResourceRequest& request = fetch_params.GetResourceRequest();
819 849
820 if (!existing_resource) 850 Resource* resource = it->value;
821 return kLoad;
822 851
823 // If the existing resource is loading and the associated fetcher is not equal 852 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch);
824 // to |this|, we must not use the resource. Otherwise, CSP violation may 853 if (resource->MustRefetchDueToIntegrityMetadata(params))
825 // happen in redirect handling. 854 return nullptr;
826 if (existing_resource->Loader() && 855
827 existing_resource->Loader()->Fetcher() != this) { 856 if (params.IsSpeculativePreload())
828 return kReload; 857 return resource;
858 if (params.IsLinkPreload()) {
859 resource->SetLinkPreload(true);
860 return resource;
829 } 861 }
830 862
831 // Checks if the resource has an explicit policy about integrity metadata. 863 if (!IsReusableForPreloading(params, resource, false))
832 // 864 return nullptr;
833 // This is necessary because ScriptResource and CSSStyleSheetResource objects 865
834 // do not keep the raw data around after the source is accessed once, so if 866 resource->DecreasePreloadCount();
835 // the resource is accessed from the MemoryCache for a second time, there is 867 preloads_.erase(it);
836 // no way to redo an integrity check. 868 return resource;
837 // 869 }
838 // Thus, Blink implements a scheme where it caches the integrity information 870
839 // for those resources after the first time it is checked, and if there is 871 void ResourceFetcher::InsertAsPreloadIfNecessary(Resource* resource,
840 // another request for that resource, with the same integrity metadata, Blink 872 const FetchParameters& params,
841 // skips the integrity calculation. However, if the integrity metadata is a 873 Resource::Type type) {
842 // mismatch, the MemoryCache must be skipped here, and a new request for the 874 // CSP layout tests verify that preloads are subject to access checks by
843 // resource must be made to get the raw data. This is expected to be an 875 // seeing if they are in the `preload started` list. Therefore do not add
844 // uncommon case, however, as it implies two same-origin requests to the same 876 // them to the list if the load is immediately denied.
845 // resource, but with different integrity metadata. 877 if ((params.IsSpeculativePreload() || params.IsLinkPreload()) &&
846 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); 878 !resource->GetResourceError().IsAccessCheck()) {
847 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { 879 PreloadKey key(params.Url(), type);
848 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); 880 if (preloads_.Find(key) == preloads_.end()) {
849 return kReload; 881 preloads_.insert(key, resource);
882 resource->IncreasePreloadCount();
883 if (preloaded_urls_for_test_)
884 preloaded_urls_for_test_->insert(resource->Url().GetString());
885 }
850 } 886 }
887 }
851 888
852 // If the same URL has been loaded as a different type, we need to reload. 889 bool ResourceFetcher::IsReusableForPreloading(const FetchParameters& params,
853 if (existing_resource->GetType() != type) { 890 Resource* existing_resource,
854 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch 891 bool is_static_data) const {
855 // We really should discard the new prefetch since the preload has more 892 const ResourceRequest& request = params.GetResourceRequest();
856 // specific type information! crbug.com/379893
857 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
858 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy "
859 "reloading due to type mismatch.";
860 return kReload;
861 }
862
863 // We already have a preload going for this URL.
864 if (fetch_params.IsSpeculativePreload() && existing_resource->IsPreloaded())
865 return kUse;
866
867 // Do not load from cache if images are not enabled. There are two general 893 // Do not load from cache if images are not enabled. There are two general
868 // cases: 894 // cases:
869 // 895 //
870 // 1. Images are disabled. Don't ever load images, even if the image is cached 896 // 1. Images are disabled. Don't ever load images, even if the image is cached
871 // or it is a data: url. In this case, we "Reload" the image, then defer it 897 // or it is a data: url. In this case, we "Reload" the image, then defer it
872 // with resourceNeedsLoad() so that it never actually goes to the network. 898 // with resourceNeedsLoad() so that it never actually goes to the network.
873 // 899 //
874 // 2. Images are enabled, but not loaded automatically. In this case, we will 900 // 2. Images are enabled, but not loaded automatically. In this case, we will
875 // Use cached resources or data: urls, but will similarly fall back to a 901 // Use cached resources or data: urls, but will similarly fall back to a
876 // deferred network load if we don't have the data available without a network 902 // deferred network load if we don't have the data available without a network
877 // request. We check allowImage() here, which is affected by m_imagesEnabled 903 // request. We check allowImage() here, which is affected by m_imagesEnabled
878 // but not m_autoLoadImages, in order to allow for this differing behavior. 904 // but not m_autoLoadImages, in order to allow for this differing behavior.
879 // 905 //
880 // TODO(japhet): Can we get rid of one of these settings? 906 // TODO(japhet): Can we get rid of one of these settings?
881 if (existing_resource->IsImage() && 907 if (existing_resource->IsImage() &&
882 !Context().AllowImage(images_enabled_, existing_resource->Url())) { 908 !Context().AllowImage(images_enabled_, existing_resource->Url())) {
883 return kReload; 909 return false;
884 } 910 }
885 911
886 // Never use cache entries for downloadToFile / useStreamOnResponse requests. 912 // Never use cache entries for downloadToFile / useStreamOnResponse requests.
887 // The data will be delivered through other paths. 913 // The data will be delivered through other paths.
888 if (request.DownloadToFile() || request.UseStreamOnResponse()) 914 if (request.DownloadToFile() || request.UseStreamOnResponse())
889 return kReload; 915 return false;
890 916
891 // Never reuse opaque responses from a service worker for requests that are 917 // Never reuse opaque responses from a service worker for requests that are
892 // not no-cors. https://crbug.com/625575 918 // not no-cors. https://crbug.com/625575
893 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && 919 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() &&
894 existing_resource->GetResponse().ServiceWorkerResponseType() == 920 existing_resource->GetResponse().ServiceWorkerResponseType() ==
895 kWebServiceWorkerResponseTypeOpaque && 921 kWebServiceWorkerResponseTypeOpaque &&
896 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { 922 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) {
897 return kReload; 923 return false;
898 } 924 }
899 925
900 if (!is_static_data && !existing_resource->CanReuse(fetch_params)) 926 if (!is_static_data && !existing_resource->CanReuse(params))
901 return kReload; 927 return false;
902 928
903 // Certain requests (e.g., XHRs) might have manually set headers that require 929 // Certain requests (e.g., XHRs) might have manually set headers that require
904 // revalidation. In theory, this should be a Revalidate case. In practice, the 930 // revalidation. In theory, this should be a Revalidate case. In practice, the
905 // MemoryCache revalidation path assumes a whole bunch of things about how 931 // MemoryCache revalidation path assumes a whole bunch of things about how
906 // revalidation works that manual headers violate, so punt to Reload instead. 932 // revalidation works that manual headers violate, so punt to Reload instead.
907 // 933 //
908 // Similarly, a request with manually added revalidation headers can lead to a 934 // Similarly, a request with manually added revalidation headers can lead to a
909 // 304 response for a request that wasn't flagged as a revalidation attempt. 935 // 304 response for a request that wasn't flagged as a revalidation attempt.
910 // Normally, successful revalidation will maintain the original response's 936 // Normally, successful revalidation will maintain the original response's
911 // status code, but for a manual revalidation the response code remains 304. 937 // status code, but for a manual revalidation the response code remains 304.
912 // In this case, the Resource likely has insufficient context to provide a 938 // In this case, the Resource likely has insufficient context to provide a
913 // useful cache hit or revalidation. See http://crbug.com/643659 939 // useful cache hit or revalidation. See http://crbug.com/643659
914 if (!is_static_data && 940 if (!is_static_data &&
915 (request.IsConditional() || 941 (request.IsConditional() ||
916 existing_resource->GetResponse().HttpStatusCode() == 304)) { 942 existing_resource->GetResponse().HttpStatusCode() == 304)) {
943 return false;
944 }
945
946 if (!is_static_data &&
947 !params.Options().CanReuseRequest(existing_resource->Options())) {
948 return false;
949 }
950
951 return true;
952 }
953
954 ResourceFetcher::RevalidationPolicy
955 ResourceFetcher::DetermineRevalidationPolicy(
956 Resource::Type type,
957 const FetchParameters& fetch_params,
958 Resource* existing_resource,
959 bool is_static_data) const {
960 const ResourceRequest& request = fetch_params.GetResourceRequest();
961
962 if (!existing_resource)
963 return kLoad;
964
965 // If the existing resource is loading and the associated fetcher is not equal
966 // to |this|, we must not use the resource. Otherwise, CSP violation may
967 // happen in redirect handling.
968 if (existing_resource->Loader() &&
969 existing_resource->Loader()->Fetcher() != this) {
917 return kReload; 970 return kReload;
918 } 971 }
919 972
920 if (!is_static_data && 973 // Checks if the resource has an explicit policy about integrity metadata.
921 !fetch_params.Options().CanReuseRequest(existing_resource->Options())) { 974 //
975 // This is necessary because ScriptResource and CSSStyleSheetResource objects
976 // do not keep the raw data around after the source is accessed once, so if
977 // the resource is accessed from the MemoryCache for a second time, there is
978 // no way to redo an integrity check.
979 //
980 // Thus, Blink implements a scheme where it caches the integrity information
981 // for those resources after the first time it is checked, and if there is
982 // another request for that resource, with the same integrity metadata, Blink
983 // skips the integrity calculation. However, if the integrity metadata is a
984 // mismatch, the MemoryCache must be skipped here, and a new request for the
985 // resource must be made to get the raw data. This is expected to be an
986 // uncommon case, however, as it implies two same-origin requests to the same
987 // resource, but with different integrity metadata.
988 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch);
989 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) {
990 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch);
922 return kReload; 991 return kReload;
923 } 992 }
924 993
925 // Always use preloads. 994 // If the same URL has been loaded as a different type, we need to reload.
926 if (existing_resource->IsPreloaded()) 995 if (existing_resource->GetType() != type) {
927 return kUse; 996 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch
997 // We really should discard the new prefetch since the preload has more
998 // specific type information! crbug.com/379893
999 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
1000 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy "
1001 "reloading due to type mismatch.";
1002 return kReload;
1003 }
1004
1005 // If |existing_resource| is not reusable as a preloaded resource, it should
1006 // not be reusable as a normal resource as well.
1007 if (!IsReusableForPreloading(fetch_params, existing_resource, is_static_data))
1008 return kReload;
928 1009
929 // If resource was populated from a SubstituteData load or data: url, use it. 1010 // If resource was populated from a SubstituteData load or data: url, use it.
930 if (is_static_data) 1011 if (is_static_data)
931 return kUse; 1012 return kUse;
932 1013
933 // Don't reload resources while pasting. 1014 // Don't reload resources while pasting.
934 if (allow_stale_resources_) 1015 if (allow_stale_resources_)
935 return kUse; 1016 return kUse;
936 1017
937 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. 1018 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 } 1159 }
1079 1160
1080 int ResourceFetcher::BlockingRequestCount() const { 1161 int ResourceFetcher::BlockingRequestCount() const {
1081 return loaders_.size(); 1162 return loaders_.size();
1082 } 1163 }
1083 1164
1084 int ResourceFetcher::NonblockingRequestCount() const { 1165 int ResourceFetcher::NonblockingRequestCount() const {
1085 return non_blocking_loaders_.size(); 1166 return non_blocking_loaders_.size();
1086 } 1167 }
1087 1168
1088 void ResourceFetcher::PreloadStarted(Resource* resource) {
1089 if (preloads_.Contains(resource))
1090 return;
1091 resource->IncreasePreloadCount();
1092
1093 preloads_.insert(resource);
1094
1095 if (preloaded_urls_for_test_)
1096 preloaded_urls_for_test_->insert(resource->Url().GetString());
1097 }
1098
1099 void ResourceFetcher::EnableIsPreloadedForTest() { 1169 void ResourceFetcher::EnableIsPreloadedForTest() {
1100 if (preloaded_urls_for_test_) 1170 if (preloaded_urls_for_test_)
1101 return; 1171 return;
1102 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); 1172 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>);
1103 1173
1104 for (const auto& resource : preloads_) 1174 for (const auto& pair : preloads_) {
1175 Resource* resource = pair.value;
1105 preloaded_urls_for_test_->insert(resource->Url().GetString()); 1176 preloaded_urls_for_test_->insert(resource->Url().GetString());
1177 }
1106 } 1178 }
1107 1179
1108 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { 1180 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const {
1109 DCHECK(preloaded_urls_for_test_); 1181 DCHECK(preloaded_urls_for_test_);
1110 return preloaded_urls_for_test_->Contains(url.GetString()); 1182 return preloaded_urls_for_test_->Contains(url.GetString());
1111 } 1183 }
1112 1184
1113 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { 1185 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) {
1114 LogPreloadStats(policy); 1186 LogPreloadStats(policy);
1115 1187
1116 for (const auto& resource : preloads_) { 1188 Vector<PreloadKey> keys_to_be_removed;
1189 for (const auto& pair : preloads_) {
1190 Resource* resource = pair.value;
1117 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { 1191 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) {
1118 resource->DecreasePreloadCount(); 1192 resource->DecreasePreloadCount();
1119 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) 1193 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced)
1120 GetMemoryCache()->Remove(resource.Get()); 1194 GetMemoryCache()->Remove(resource);
1121 preloads_.erase(resource); 1195 keys_to_be_removed.push_back(pair.key);
1122 } 1196 }
1123 } 1197 }
1198 preloads_.RemoveAll(keys_to_be_removed);
1124 } 1199 }
1125 1200
1126 void ResourceFetcher::WarnUnusedPreloads() { 1201 void ResourceFetcher::WarnUnusedPreloads() {
1127 for (const auto& resource : preloads_) { 1202 for (const auto& pair : preloads_) {
1203 Resource* resource = pair.value;
1128 if (resource && resource->IsLinkPreload() && 1204 if (resource && resource->IsLinkPreload() &&
1129 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { 1205 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) {
1130 Context().AddConsoleMessage( 1206 Context().AddConsoleMessage(
1131 "The resource " + resource->Url().GetString() + 1207 "The resource " + resource->Url().GetString() +
1132 " was preloaded using link preload but not used within a few " 1208 " was preloaded using link preload but not used within a few "
1133 "seconds from the window's load event. Please make sure it " 1209 "seconds from the window's load event. Please make sure it "
1134 "wasn't preloaded for nothing.", 1210 "wasn't preloaded for nothing.",
1135 FetchContext::kLogWarningMessage); 1211 FetchContext::kLogWarningMessage);
1136 } 1212 }
1137 } 1213 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 unsigned fonts = 0; 1443 unsigned fonts = 0;
1368 unsigned font_misses = 0; 1444 unsigned font_misses = 0;
1369 unsigned medias = 0; 1445 unsigned medias = 0;
1370 unsigned media_misses = 0; 1446 unsigned media_misses = 0;
1371 unsigned text_tracks = 0; 1447 unsigned text_tracks = 0;
1372 unsigned text_track_misses = 0; 1448 unsigned text_track_misses = 0;
1373 unsigned imports = 0; 1449 unsigned imports = 0;
1374 unsigned import_misses = 0; 1450 unsigned import_misses = 0;
1375 unsigned raws = 0; 1451 unsigned raws = 0;
1376 unsigned raw_misses = 0; 1452 unsigned raw_misses = 0;
1377 for (const auto& resource : preloads_) { 1453 for (const auto& pair : preloads_) {
1454 Resource* resource = pair.value;
1378 // Do not double count link rel preloads. These do not get cleared if the 1455 // Do not double count link rel preloads. These do not get cleared if the
1379 // ClearPreloadsPolicy is only clearing speculative markup preloads. 1456 // ClearPreloadsPolicy is only clearing speculative markup preloads.
1380 if (resource->IsLinkPreload() && 1457 if (resource->IsLinkPreload() &&
1381 policy == kClearSpeculativeMarkupPreloads) { 1458 policy == kClearSpeculativeMarkupPreloads) {
1382 continue; 1459 continue;
1383 } 1460 }
1384 int miss_count = 1461 int miss_count =
1385 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; 1462 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0;
1386 switch (resource->GetType()) { 1463 switch (resource->GetType()) {
1387 case Resource::kImage: 1464 case Resource::kImage:
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 visitor->Trace(context_); 1602 visitor->Trace(context_);
1526 visitor->Trace(archive_); 1603 visitor->Trace(archive_);
1527 visitor->Trace(loaders_); 1604 visitor->Trace(loaders_);
1528 visitor->Trace(non_blocking_loaders_); 1605 visitor->Trace(non_blocking_loaders_);
1529 visitor->Trace(document_resources_); 1606 visitor->Trace(document_resources_);
1530 visitor->Trace(preloads_); 1607 visitor->Trace(preloads_);
1531 visitor->Trace(resource_timing_info_map_); 1608 visitor->Trace(resource_timing_info_map_);
1532 } 1609 }
1533 1610
1534 } // namespace blink 1611 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698