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

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

Issue 2871233002: Separate preload matching from MemoryCache (Closed)
Patch Set: rebase 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 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { 486 if (params.IsSpeculativePreload() || params.IsLinkPreload()) {
487 DEFINE_RESOURCE_HISTOGRAM("Preload."); 487 DEFINE_RESOURCE_HISTOGRAM("Preload.");
488 } else { 488 } else {
489 DEFINE_RESOURCE_HISTOGRAM(""); 489 DEFINE_RESOURCE_HISTOGRAM("");
490 } 490 }
491 491
492 // Aims to count Resource only referenced from MemoryCache (i.e. what would be 492 // Aims to count Resource only referenced from MemoryCache (i.e. what would be
493 // dead if MemoryCache holds weak references to Resource). Currently we check 493 // dead if MemoryCache holds weak references to Resource). Currently we check
494 // references to Resource from ResourceClient and |m_preloads| only, because 494 // references to Resource from ResourceClient and |m_preloads| only, because
495 // they are major sources of references. 495 // they are major sources of references.
496 if (resource && !resource->IsAlive() && !preloads_.Contains(resource)) { 496 if (resource && !resource->IsAlive() && !ContainsAsPreload(resource)) {
497 DEFINE_RESOURCE_HISTOGRAM("Dead."); 497 DEFINE_RESOURCE_HISTOGRAM("Dead.");
498 } 498 }
499 } 499 }
500 500
501 bool ResourceFetcher::ContainsAsPreload(Resource* resource) const {
502 auto it = preloads_.find(PreloadKey(resource->Url(), resource->GetType()));
503 return it != preloads_.end() && it->value == resource;
504 }
505
506 void ResourceFetcher::RemovePreload(Resource* resource) {
507 auto it = preloads_.find(PreloadKey(resource->Url(), resource->GetType()));
508 if (it == preloads_.end())
509 return;
510 if (it->value == resource) {
511 resource->DecreasePreloadCount();
512 preloads_.erase(it);
513 }
514 }
515
501 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( 516 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest(
502 FetchParameters& params, 517 FetchParameters& params,
503 const ResourceFactory& factory, 518 const ResourceFactory& factory,
504 const SubstituteData& substitute_data, 519 const SubstituteData& substitute_data,
505 unsigned long identifier, 520 unsigned long identifier,
506 ResourceRequestBlockedReason& blocked_reason) { 521 ResourceRequestBlockedReason& blocked_reason) {
507 ResourceRequest& resource_request = params.MutableResourceRequest(); 522 ResourceRequest& resource_request = params.MutableResourceRequest();
508 523
509 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || 524 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously ||
510 factory.GetType() == Resource::kRaw || 525 factory.GetType() == Resource::kRaw ||
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; 612 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_;
598 if (is_static_data) { 613 if (is_static_data) {
599 resource = ResourceForStaticData(params, factory, substitute_data); 614 resource = ResourceForStaticData(params, factory, substitute_data);
600 // Abort the request if the archive doesn't contain the resource, except in 615 // Abort the request if the archive doesn't contain the resource, except in
601 // the case of data URLs which might have resources such as fonts that need 616 // the case of data URLs which might have resources such as fonts that need
602 // to be decoded only on demand. These data URLs are allowed to be 617 // to be decoded only on demand. These data URLs are allowed to be
603 // processed using the normal ResourceFetcher machinery. 618 // processed using the normal ResourceFetcher machinery.
604 if (!resource && !is_data_url && archive_) 619 if (!resource && !is_data_url && archive_)
605 return nullptr; 620 return nullptr;
606 } 621 }
622 RevalidationPolicy policy = kLoad;
623 bool preload_found = false;
607 if (!resource) { 624 if (!resource) {
608 resource = 625 resource = MatchPreload(params, factory.GetType());
609 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); 626 if (resource) {
627 preload_found = true;
628 policy = kUse;
629 // If |param| is for a blocking resource and a preloaded resource is
630 // found, we may need to make it block the onload event.
631 MakePreloadedResourceBlockOnloadIfNeeded(resource, params);
632 }
610 } 633 }
634 if (!preload_found) {
635 if (!resource) {
636 resource =
637 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier());
638 }
611 639
612 // If we got a preloaded resource from the cache for a non-preload request, 640 policy = DetermineRevalidationPolicy(factory.GetType(), params, resource,
613 // we may need to make it block the onload event. 641 is_static_data);
614 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); 642 TRACE_EVENT_INSTANT1(
615 643 "blink", "ResourceFetcher::determineRevalidationPolicy",
616 const RevalidationPolicy policy = DetermineRevalidationPolicy( 644 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy);
617 factory.GetType(), params, resource, is_static_data); 645 }
618 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy",
619 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy);
620 646
621 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); 647 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data);
622 648
623 switch (policy) { 649 switch (policy) {
624 case kReload: 650 case kReload:
625 GetMemoryCache()->Remove(resource); 651 GetMemoryCache()->Remove(resource);
626 // Fall through 652 // Fall through
627 case kLoad: 653 case kLoad:
628 resource = CreateResourceForLoading(params, params.Charset(), factory); 654 resource = CreateResourceForLoading(params, params.Charset(), factory);
629 break; 655 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 // If only the fragment identifiers differ, it is the same resource. 688 // If only the fragment identifiers differ, it is the same resource.
663 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); 689 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url()));
664 RequestLoadStarted(identifier, resource, params, policy, is_static_data); 690 RequestLoadStarted(identifier, resource, params, policy, is_static_data);
665 document_resources_.Set( 691 document_resources_.Set(
666 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); 692 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource);
667 693
668 // Returns with an existing resource if the resource does not need to start 694 // Returns with an existing resource if the resource does not need to start
669 // loading immediately. If revalidation policy was determined as |Revalidate|, 695 // loading immediately. If revalidation policy was determined as |Revalidate|,
670 // the resource was already initialized for the revalidation here, but won't 696 // the resource was already initialized for the revalidation here, but won't
671 // start loading. 697 // start loading.
672 if (!ResourceNeedsLoad(resource, params, policy)) 698 if (!ResourceNeedsLoad(resource, params, policy)) {
699 if (policy != kUse)
700 InsertAsPreloadIfNecessary(resource, params, factory.GetType());
673 return resource; 701 return resource;
702 }
674 703
675 if (!StartLoad(resource)) 704 if (!StartLoad(resource))
676 return nullptr; 705 return nullptr;
706
707 if (policy != kUse)
708 InsertAsPreloadIfNecessary(resource, params, factory.GetType());
677 scoped_resource_load_tracker.ResourceLoadContinuesBeyondScope(); 709 scoped_resource_load_tracker.ResourceLoadContinuesBeyondScope();
678 710
679 DCHECK(!resource->ErrorOccurred() || 711 DCHECK(!resource->ErrorOccurred() ||
680 params.Options().synchronous_policy == kRequestSynchronously); 712 params.Options().synchronous_policy == kRequestSynchronously);
681 return resource; 713 return resource;
682 } 714 }
683 715
684 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { 716 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) {
685 DCHECK_EQ(timer, &resource_timing_report_timer_); 717 DCHECK_EQ(timer, &resource_timing_report_timer_);
686 Vector<RefPtr<ResourceTimingInfo>> timing_reports; 718 Vector<RefPtr<ResourceTimingInfo>> timing_reports;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 resource->SetLinkPreload(params.IsLinkPreload()); 794 resource->SetLinkPreload(params.IsLinkPreload());
763 if (params.IsSpeculativePreload()) { 795 if (params.IsSpeculativePreload()) {
764 resource->SetPreloadDiscoveryTime(params.PreloadDiscoveryTime()); 796 resource->SetPreloadDiscoveryTime(params.PreloadDiscoveryTime());
765 } 797 }
766 resource->SetCacheIdentifier(cache_identifier); 798 resource->SetCacheIdentifier(cache_identifier);
767 799
768 // - Don't add main resource to cache to prevent reuse. 800 // - Don't add main resource to cache to prevent reuse.
769 // - Don't add the resource if its body will not be stored. 801 // - Don't add the resource if its body will not be stored.
770 if (factory.GetType() != Resource::kMainResource && 802 if (factory.GetType() != Resource::kMainResource &&
771 params.Options().data_buffering_policy != kDoNotBufferData) { 803 params.Options().data_buffering_policy != kDoNotBufferData) {
772 GetMemoryCache()->Add(resource); 804 GetMemoryCache()->Add(resource);
Yoav Weiss 2017/05/12 16:53:46 Won't this add preloaded resources also to the mem
yhirano 2017/05/16 11:19:24 Yes, this CL changes how to match preloads, and do
773 } 805 }
774 return resource; 806 return resource;
775 } 807 }
776 808
777 void ResourceFetcher::StorePerformanceTimingInitiatorInformation( 809 void ResourceFetcher::StorePerformanceTimingInitiatorInformation(
778 Resource* resource) { 810 Resource* resource) {
779 const AtomicString& fetch_initiator = resource->Options().initiator_info.name; 811 const AtomicString& fetch_initiator = resource->Options().initiator_info.name;
780 if (fetch_initiator == FetchInitiatorTypeNames::internal) 812 if (fetch_initiator == FetchInitiatorTypeNames::internal)
781 return; 813 return;
782 814
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 if (it != resource_timing_info_map_.end()) { 852 if (it != resource_timing_info_map_.end()) {
821 it->value->AddRedirect(redirect_response, cross_origin); 853 it->value->AddRedirect(redirect_response, cross_origin);
822 } 854 }
823 855
824 if (resource->GetType() == Resource::kMainResource) { 856 if (resource->GetType() == Resource::kMainResource) {
825 DCHECK(navigation_timing_info_); 857 DCHECK(navigation_timing_info_);
826 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); 858 navigation_timing_info_->AddRedirect(redirect_response, cross_origin);
827 } 859 }
828 } 860 }
829 861
830 ResourceFetcher::RevalidationPolicy 862 Resource* ResourceFetcher::MatchPreload(const FetchParameters& params,
831 ResourceFetcher::DetermineRevalidationPolicy( 863 Resource::Type type) {
832 Resource::Type type, 864 auto it = preloads_.find(PreloadKey(params.Url(), type));
833 const FetchParameters& fetch_params, 865 if (it == preloads_.end())
834 Resource* existing_resource, 866 return nullptr;
835 bool is_static_data) const {
836 const ResourceRequest& request = fetch_params.GetResourceRequest();
837 867
838 if (!existing_resource) 868 Resource* resource = it->value;
839 return kLoad;
840 869
841 // If the existing resource is loading and the associated fetcher is not equal 870 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch);
842 // to |this|, we must not use the resource. Otherwise, CSP violation may 871 if (resource->MustRefetchDueToIntegrityMetadata(params))
843 // happen in redirect handling. 872 return nullptr;
844 if (existing_resource->Loader() && 873
845 existing_resource->Loader()->Fetcher() != this) { 874 if (params.IsSpeculativePreload())
846 return kReload; 875 return resource;
876 if (params.IsLinkPreload()) {
877 resource->SetLinkPreload(true);
878 return resource;
847 } 879 }
848 880
849 // Checks if the resource has an explicit policy about integrity metadata. 881 if (!IsReusableForPreloading(params, resource, false))
850 // 882 return nullptr;
851 // This is necessary because ScriptResource and CSSStyleSheetResource objects 883
852 // do not keep the raw data around after the source is accessed once, so if 884 resource->DecreasePreloadCount();
853 // the resource is accessed from the MemoryCache for a second time, there is 885 preloads_.erase(it);
854 // no way to redo an integrity check. 886 matched_preloads_.push_back(resource);
855 // 887 return resource;
856 // Thus, Blink implements a scheme where it caches the integrity information 888 }
857 // for those resources after the first time it is checked, and if there is 889
858 // another request for that resource, with the same integrity metadata, Blink 890 void ResourceFetcher::InsertAsPreloadIfNecessary(Resource* resource,
859 // skips the integrity calculation. However, if the integrity metadata is a 891 const FetchParameters& params,
860 // mismatch, the MemoryCache must be skipped here, and a new request for the 892 Resource::Type type) {
861 // resource must be made to get the raw data. This is expected to be an 893 if (!params.IsSpeculativePreload() && !params.IsLinkPreload())
862 // uncommon case, however, as it implies two same-origin requests to the same 894 return;
863 // resource, but with different integrity metadata. 895 // CSP layout tests verify that preloads are subject to access checks by
864 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); 896 // seeing if they are in the `preload started` list. Therefore do not add
865 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { 897 // them to the list if the load is immediately denied.
866 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); 898 if (resource->GetResourceError().IsAccessCheck())
867 return kReload; 899 return;
900 PreloadKey key(params.Url(), type);
901 if (preloads_.find(key) == preloads_.end()) {
902 preloads_.insert(key, resource);
903 resource->IncreasePreloadCount();
904 if (preloaded_urls_for_test_)
905 preloaded_urls_for_test_->insert(resource->Url().GetString());
868 } 906 }
907 }
869 908
870 // If the same URL has been loaded as a different type, we need to reload. 909 bool ResourceFetcher::IsReusableForPreloading(const FetchParameters& params,
871 if (existing_resource->GetType() != type) { 910 Resource* existing_resource,
872 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch 911 bool is_static_data) const {
873 // We really should discard the new prefetch since the preload has more 912 const ResourceRequest& request = params.GetResourceRequest();
874 // specific type information! crbug.com/379893
875 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
876 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy "
877 "reloading due to type mismatch.";
878 return kReload;
879 }
880
881 // We already have a preload going for this URL.
882 if (fetch_params.IsSpeculativePreload() && existing_resource->IsPreloaded())
883 return kUse;
884
885 // Do not load from cache if images are not enabled. There are two general 913 // Do not load from cache if images are not enabled. There are two general
886 // cases: 914 // cases:
887 // 915 //
888 // 1. Images are disabled. Don't ever load images, even if the image is cached 916 // 1. Images are disabled. Don't ever load images, even if the image is cached
889 // or it is a data: url. In this case, we "Reload" the image, then defer it 917 // or it is a data: url. In this case, we "Reload" the image, then defer it
890 // with resourceNeedsLoad() so that it never actually goes to the network. 918 // with resourceNeedsLoad() so that it never actually goes to the network.
891 // 919 //
892 // 2. Images are enabled, but not loaded automatically. In this case, we will 920 // 2. Images are enabled, but not loaded automatically. In this case, we will
893 // Use cached resources or data: urls, but will similarly fall back to a 921 // Use cached resources or data: urls, but will similarly fall back to a
894 // deferred network load if we don't have the data available without a network 922 // deferred network load if we don't have the data available without a network
895 // request. We check allowImage() here, which is affected by m_imagesEnabled 923 // request. We check allowImage() here, which is affected by m_imagesEnabled
896 // but not m_autoLoadImages, in order to allow for this differing behavior. 924 // but not m_autoLoadImages, in order to allow for this differing behavior.
897 // 925 //
898 // TODO(japhet): Can we get rid of one of these settings? 926 // TODO(japhet): Can we get rid of one of these settings?
899 if (existing_resource->IsImage() && 927 if (existing_resource->IsImage() &&
900 !Context().AllowImage(images_enabled_, existing_resource->Url())) { 928 !Context().AllowImage(images_enabled_, existing_resource->Url())) {
901 return kReload; 929 return false;
902 } 930 }
903 931
904 // Never use cache entries for downloadToFile / useStreamOnResponse requests. 932 // Never use cache entries for downloadToFile / useStreamOnResponse requests.
905 // The data will be delivered through other paths. 933 // The data will be delivered through other paths.
906 if (request.DownloadToFile() || request.UseStreamOnResponse()) 934 if (request.DownloadToFile() || request.UseStreamOnResponse())
907 return kReload; 935 return false;
908 936
909 // Never reuse opaque responses from a service worker for requests that are 937 // Never reuse opaque responses from a service worker for requests that are
910 // not no-cors. https://crbug.com/625575 938 // not no-cors. https://crbug.com/625575
911 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && 939 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() &&
912 existing_resource->GetResponse().ServiceWorkerResponseType() == 940 existing_resource->GetResponse().ServiceWorkerResponseType() ==
913 kWebServiceWorkerResponseTypeOpaque && 941 kWebServiceWorkerResponseTypeOpaque &&
914 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { 942 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) {
915 return kReload; 943 return false;
916 } 944 }
917 945
918 if (!is_static_data && !existing_resource->CanReuse(fetch_params)) 946 if (!is_static_data && !existing_resource->CanReuse(params))
919 return kReload; 947 return false;
920 948
921 // Certain requests (e.g., XHRs) might have manually set headers that require 949 // Certain requests (e.g., XHRs) might have manually set headers that require
922 // revalidation. In theory, this should be a Revalidate case. In practice, the 950 // revalidation. In theory, this should be a Revalidate case. In practice, the
923 // MemoryCache revalidation path assumes a whole bunch of things about how 951 // MemoryCache revalidation path assumes a whole bunch of things about how
924 // revalidation works that manual headers violate, so punt to Reload instead. 952 // revalidation works that manual headers violate, so punt to Reload instead.
925 // 953 //
926 // Similarly, a request with manually added revalidation headers can lead to a 954 // Similarly, a request with manually added revalidation headers can lead to a
927 // 304 response for a request that wasn't flagged as a revalidation attempt. 955 // 304 response for a request that wasn't flagged as a revalidation attempt.
928 // Normally, successful revalidation will maintain the original response's 956 // Normally, successful revalidation will maintain the original response's
929 // status code, but for a manual revalidation the response code remains 304. 957 // status code, but for a manual revalidation the response code remains 304.
930 // In this case, the Resource likely has insufficient context to provide a 958 // In this case, the Resource likely has insufficient context to provide a
931 // useful cache hit or revalidation. See http://crbug.com/643659 959 // useful cache hit or revalidation. See http://crbug.com/643659
932 if (!is_static_data && 960 if (!is_static_data &&
933 (request.IsConditional() || 961 (request.IsConditional() ||
934 existing_resource->GetResponse().HttpStatusCode() == 304)) { 962 existing_resource->GetResponse().HttpStatusCode() == 304)) {
963 return false;
964 }
965
966 if (!is_static_data &&
967 !params.Options().CanReuseRequest(existing_resource->Options())) {
968 return false;
969 }
970
971 return true;
972 }
973
974 ResourceFetcher::RevalidationPolicy
975 ResourceFetcher::DetermineRevalidationPolicy(
976 Resource::Type type,
977 const FetchParameters& fetch_params,
978 Resource* existing_resource,
979 bool is_static_data) const {
980 const ResourceRequest& request = fetch_params.GetResourceRequest();
981
982 if (!existing_resource)
983 return kLoad;
984
985 // If the existing resource is loading and the associated fetcher is not equal
986 // to |this|, we must not use the resource. Otherwise, CSP violation may
987 // happen in redirect handling.
988 if (existing_resource->Loader() &&
989 existing_resource->Loader()->Fetcher() != this) {
935 return kReload; 990 return kReload;
936 } 991 }
937 992
938 if (!is_static_data && 993 // Checks if the resource has an explicit policy about integrity metadata.
939 !fetch_params.Options().CanReuseRequest(existing_resource->Options())) { 994 //
995 // This is necessary because ScriptResource and CSSStyleSheetResource objects
996 // do not keep the raw data around after the source is accessed once, so if
997 // the resource is accessed from the MemoryCache for a second time, there is
998 // no way to redo an integrity check.
999 //
1000 // Thus, Blink implements a scheme where it caches the integrity information
1001 // for those resources after the first time it is checked, and if there is
1002 // another request for that resource, with the same integrity metadata, Blink
1003 // skips the integrity calculation. However, if the integrity metadata is a
1004 // mismatch, the MemoryCache must be skipped here, and a new request for the
1005 // resource must be made to get the raw data. This is expected to be an
1006 // uncommon case, however, as it implies two same-origin requests to the same
1007 // resource, but with different integrity metadata.
1008 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch);
1009 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) {
1010 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch);
940 return kReload; 1011 return kReload;
941 } 1012 }
942 1013
943 // Always use preloads. 1014 // If the same URL has been loaded as a different type, we need to reload.
944 if (existing_resource->IsPreloaded()) 1015 if (existing_resource->GetType() != type) {
945 return kUse; 1016 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch
1017 // We really should discard the new prefetch since the preload has more
1018 // specific type information! crbug.com/379893
1019 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
1020 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy "
1021 "reloading due to type mismatch.";
1022 return kReload;
1023 }
1024
1025 // If |existing_resource| is not reusable as a preloaded resource, it should
1026 // not be reusable as a normal resource as well.
1027 if (!IsReusableForPreloading(fetch_params, existing_resource, is_static_data))
Yoav Weiss 2017/05/12 16:33:57 Can we maybe change the name of `isReusableForPrel
kinuko 2017/05/15 02:09:04 +1, felt slightly confusing.
yhirano 2017/05/16 11:19:24 I couldn't come up with a better name. Do you have
kinuko 2017/05/16 22:58:53 IsReusableAlsoForPreloading ...? (I'm not good at
yhirano 2017/05/17 04:24:44 Done.
1028 return kReload;
946 1029
947 // If resource was populated from a SubstituteData load or data: url, use it. 1030 // If resource was populated from a SubstituteData load or data: url, use it.
948 if (is_static_data) 1031 if (is_static_data)
949 return kUse; 1032 return kUse;
950 1033
951 // Don't reload resources while pasting. 1034 // Don't reload resources while pasting.
952 if (allow_stale_resources_) 1035 if (allow_stale_resources_)
953 return kUse; 1036 return kUse;
954 1037
955 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. 1038 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 1179 }
1097 1180
1098 int ResourceFetcher::BlockingRequestCount() const { 1181 int ResourceFetcher::BlockingRequestCount() const {
1099 return loaders_.size(); 1182 return loaders_.size();
1100 } 1183 }
1101 1184
1102 int ResourceFetcher::NonblockingRequestCount() const { 1185 int ResourceFetcher::NonblockingRequestCount() const {
1103 return non_blocking_loaders_.size(); 1186 return non_blocking_loaders_.size();
1104 } 1187 }
1105 1188
1106 void ResourceFetcher::PreloadStarted(Resource* resource) {
1107 if (preloads_.Contains(resource))
1108 return;
1109 resource->IncreasePreloadCount();
1110
1111 preloads_.insert(resource);
1112
1113 if (preloaded_urls_for_test_)
1114 preloaded_urls_for_test_->insert(resource->Url().GetString());
1115 }
1116
1117 void ResourceFetcher::EnableIsPreloadedForTest() { 1189 void ResourceFetcher::EnableIsPreloadedForTest() {
1118 if (preloaded_urls_for_test_) 1190 if (preloaded_urls_for_test_)
1119 return; 1191 return;
1120 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); 1192 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>);
1121 1193
1122 for (const auto& resource : preloads_) 1194 for (const auto& pair : preloads_) {
1195 Resource* resource = pair.value;
1123 preloaded_urls_for_test_->insert(resource->Url().GetString()); 1196 preloaded_urls_for_test_->insert(resource->Url().GetString());
1197 }
1124 } 1198 }
1125 1199
1126 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { 1200 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const {
1127 DCHECK(preloaded_urls_for_test_); 1201 DCHECK(preloaded_urls_for_test_);
1128 return preloaded_urls_for_test_->Contains(url.GetString()); 1202 return preloaded_urls_for_test_->Contains(url.GetString());
1129 } 1203 }
1130 1204
1131 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { 1205 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) {
1132 LogPreloadStats(policy); 1206 LogPreloadStats(policy);
1133 1207
1134 for (const auto& resource : preloads_) { 1208 Vector<PreloadKey> keys_to_be_removed;
1209 for (const auto& pair : preloads_) {
1210 Resource* resource = pair.value;
1135 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { 1211 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) {
1136 resource->DecreasePreloadCount(); 1212 resource->DecreasePreloadCount();
1137 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) 1213 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced)
1138 GetMemoryCache()->Remove(resource.Get()); 1214 GetMemoryCache()->Remove(resource);
1139 preloads_.erase(resource); 1215 keys_to_be_removed.push_back(pair.key);
1140 } 1216 }
1141 } 1217 }
1218 preloads_.RemoveAll(keys_to_be_removed);
1219
1220 matched_preloads_.clear();
1142 } 1221 }
1143 1222
1144 void ResourceFetcher::WarnUnusedPreloads() { 1223 void ResourceFetcher::WarnUnusedPreloads() {
1145 for (const auto& resource : preloads_) { 1224 for (const auto& pair : preloads_) {
1225 Resource* resource = pair.value;
1146 if (resource && resource->IsLinkPreload() && 1226 if (resource && resource->IsLinkPreload() &&
1147 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { 1227 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) {
1148 Context().AddConsoleMessage( 1228 Context().AddConsoleMessage(
1149 "The resource " + resource->Url().GetString() + 1229 "The resource " + resource->Url().GetString() +
1150 " was preloaded using link preload but not used within a few " 1230 " was preloaded using link preload but not used within a few "
1151 "seconds from the window's load event. Please make sure it " 1231 "seconds from the window's load event. Please make sure it "
1152 "wasn't preloaded for nothing.", 1232 "wasn't preloaded for nothing.",
1153 FetchContext::kLogWarningMessage); 1233 FetchContext::kLogWarningMessage);
1154 } 1234 }
1155 } 1235 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 1322
1243 resource_timing_info_map_.Take(resource); 1323 resource_timing_info_map_.Take(resource);
1244 1324
1245 bool is_internal_request = resource->Options().initiator_info.name == 1325 bool is_internal_request = resource->Options().initiator_info.name ==
1246 FetchInitiatorTypeNames::internal; 1326 FetchInitiatorTypeNames::internal;
1247 1327
1248 Context().DispatchDidFail(resource->Identifier(), error, 1328 Context().DispatchDidFail(resource->Identifier(), error,
1249 resource->GetResponse().EncodedDataLength(), 1329 resource->GetResponse().EncodedDataLength(),
1250 is_internal_request); 1330 is_internal_request);
1251 1331
1332 if (error.IsCancellation())
1333 RemovePreload(resource);
1252 resource->FinishAsError(error); 1334 resource->FinishAsError(error);
1253 1335
1254 HandleLoadCompletion(resource); 1336 HandleLoadCompletion(resource);
1255 } 1337 }
1256 1338
1257 void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { 1339 void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) {
1258 DCHECK(loader); 1340 DCHECK(loader);
1259 // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in. 1341 // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in.
1260 CHECK(loaders_.Contains(loader)); 1342 CHECK(loaders_.Contains(loader));
1261 non_blocking_loaders_.insert(loader); 1343 non_blocking_loaders_.insert(loader);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 unsigned fonts = 0; 1482 unsigned fonts = 0;
1401 unsigned font_misses = 0; 1483 unsigned font_misses = 0;
1402 unsigned medias = 0; 1484 unsigned medias = 0;
1403 unsigned media_misses = 0; 1485 unsigned media_misses = 0;
1404 unsigned text_tracks = 0; 1486 unsigned text_tracks = 0;
1405 unsigned text_track_misses = 0; 1487 unsigned text_track_misses = 0;
1406 unsigned imports = 0; 1488 unsigned imports = 0;
1407 unsigned import_misses = 0; 1489 unsigned import_misses = 0;
1408 unsigned raws = 0; 1490 unsigned raws = 0;
1409 unsigned raw_misses = 0; 1491 unsigned raw_misses = 0;
1410 for (const auto& resource : preloads_) { 1492 for (const auto& pair : preloads_) {
1493 Resource* resource = pair.value;
1411 // Do not double count link rel preloads. These do not get cleared if the 1494 // Do not double count link rel preloads. These do not get cleared if the
1412 // ClearPreloadsPolicy is only clearing speculative markup preloads. 1495 // ClearPreloadsPolicy is only clearing speculative markup preloads.
1413 if (resource->IsLinkPreload() && 1496 if (resource->IsLinkPreload() &&
1414 policy == kClearSpeculativeMarkupPreloads) { 1497 policy == kClearSpeculativeMarkupPreloads) {
1415 continue; 1498 continue;
1416 } 1499 }
1417 int miss_count = 1500 int miss_count =
1418 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; 1501 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0;
1419 switch (resource->GetType()) { 1502 switch (resource->GetType()) {
1420 case Resource::kImage: 1503 case Resource::kImage:
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 RequestLoadStarted(resource->Identifier(), resource, params, kUse); 1637 RequestLoadStarted(resource->Identifier(), resource, params, kUse);
1555 } 1638 }
1556 1639
1557 DEFINE_TRACE(ResourceFetcher) { 1640 DEFINE_TRACE(ResourceFetcher) {
1558 visitor->Trace(context_); 1641 visitor->Trace(context_);
1559 visitor->Trace(archive_); 1642 visitor->Trace(archive_);
1560 visitor->Trace(loaders_); 1643 visitor->Trace(loaders_);
1561 visitor->Trace(non_blocking_loaders_); 1644 visitor->Trace(non_blocking_loaders_);
1562 visitor->Trace(document_resources_); 1645 visitor->Trace(document_resources_);
1563 visitor->Trace(preloads_); 1646 visitor->Trace(preloads_);
1647 visitor->Trace(matched_preloads_);
1564 visitor->Trace(resource_timing_info_map_); 1648 visitor->Trace(resource_timing_info_map_);
1565 } 1649 }
1566 1650
1567 } // namespace blink 1651 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698