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

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

Powered by Google App Engine
This is Rietveld 408576698