Changeset 20182 in webkit


Ignore:
Timestamp:
Mar 14, 2007 1:07:59 AM (17 years ago)
Author:
hyatt
Message:

WebCore:

Fix for bugzilla bug 13050 and also radar p1 5050645.

This patch reworks resource loading to avoid having redundant buffers in the icon database and in cached
images in the WebCore cache. It also avoids overcopying in top-level image documents and in the icon
database.

There is now only one SharedBuffer for a resource and everybody observes that buffer now instead of ever
making their own. Even ImageIO uses the SharedBuffer while decoding.

The page in 13050 dropped from 145mb down to 45mb of memory use with this change for a stunning savings
of 100mb.

Reviewed by olliej, mjs

  • WebCore.exp:
  • loader/CachedCSSStyleSheet.cpp: (WebCore::CachedCSSStyleSheet::data):
  • loader/CachedCSSStyleSheet.h:
  • loader/CachedImage.cpp: (WebCore::CachedImage::data):
  • loader/CachedImage.h:
  • loader/CachedResource.cpp: (WebCore::CachedResource::CachedResource): (WebCore::CachedResource::~CachedResource):
  • loader/CachedResource.h: (WebCore::CachedResource::data):
  • loader/CachedScript.cpp: (WebCore::CachedScript::data):
  • loader/CachedScript.h:
  • loader/CachedXSLStyleSheet.cpp: (WebCore::CachedXSLStyleSheet::data):
  • loader/CachedXSLStyleSheet.h:
  • loader/DocLoader.cpp: (WebCore::DocLoader::checkCacheObjectStatus):
  • loader/ImageDocument.cpp: (WebCore::ImageTokenizer::writeRawData): (WebCore::ImageTokenizer::finish):
  • loader/icon/IconDataCache.cpp: (WebCore::IconDataCache::setImageData): (WebCore::IconDataCache::writeToDatabase):
  • loader/icon/IconDataCache.h:
  • loader/icon/IconDatabase.cpp: (WebCore::IconDatabase::imageDataForIconURL): (WebCore::IconDatabase::iconForPageURL): (WebCore::IconDatabase::setIconDataForIconURL): (WebCore::IconDatabase::setHaveNoIconForIconURL): (WebCore::IconDatabase::imageDataForIconURLQuery):
  • loader/icon/IconDatabase.h:
  • loader/icon/IconLoader.cpp: (WebCore::IconLoader::startLoading): (WebCore::IconLoader::didReceiveResponse): (WebCore::IconLoader::didReceiveData): (WebCore::IconLoader::didFail): (WebCore::IconLoader::finishLoading): (WebCore::IconLoader::clearLoadingState):
  • loader/icon/IconLoader.h:
  • loader/icon/SQLStatement.cpp: (WebCore::SQLStatement::getColumnBlobAsVector): (WebCore::SQLStatement::isExpired):
  • loader/icon/SQLStatement.h:
  • loader/loader.cpp: (WebCore::Loader::didFinishLoading): (WebCore::Loader::didReceiveData):
  • page/mac/WebCoreFrameBridge.mm: (-[WebCoreFrameBridge getData:andResponse:forURL:]): (-[WebCoreFrameBridge getAllResourceDatas:andResponses:]):
  • platform/SharedBuffer.h: (WebCore::SharedBuffer::isEmpty):
  • platform/graphics/BitmapImage.cpp: (WebCore::BitmapImage::destroyDecodedData): (WebCore::BitmapImage::dataChanged):
  • platform/graphics/BitmapImage.h:
  • platform/graphics/Image.cpp: (WebCore::Image::setData):
  • platform/graphics/Image.h: (WebCore::Image::dataChanged): (WebCore::Image::data):
  • platform/graphics/ImageSource.h:
  • platform/graphics/cg/ImageSourceCG.cpp: (WebCore::ImageSource::setData):
  • platform/graphics/cg/PDFDocumentImage.cpp: (WebCore::PDFDocumentImage::dataChanged):
  • platform/graphics/cg/PDFDocumentImage.h:
  • platform/graphics/mac/ImageMac.mm: (WebCore::Image::loadPlatformResource):
  • platform/graphics/svg/SVGImage.cpp: (WebCore::SVGImage::setData):
  • platform/mac/PasteboardMac.mm: (WebCore::fileWrapperForImage):

WebKit:

Fixes to ensure that the resource loader's shared buffer can always be used.

Reviewed by olliej, mjs

  • Misc/WebIconDatabase.mm: (-[WebIconDatabase _convertToWebCoreFormat]):
  • WebCoreSupport/WebFrameLoaderClient.mm: (WebFrameLoaderClient::deliverArchivedResources):
Location:
trunk
Files:
40 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r20181 r20182  
     12007-03-13  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for bugzilla bug 13050 and also radar p1 5050645.
     4
     5        This patch reworks resource loading to avoid having redundant buffers in the icon database and in cached
     6        images in the WebCore cache.  It also avoids overcopying in top-level image documents and in the icon
     7        database.
     8
     9        There is now only one SharedBuffer for a resource and everybody observes that buffer now instead of ever
     10        making their own.  Even ImageIO uses the SharedBuffer while decoding.
     11
     12        The page in 13050 dropped from 145mb down to 45mb of memory use with this change for a stunning savings
     13        of 100mb.
     14
     15        Reviewed by olliej, mjs
     16
     17        * WebCore.exp:
     18        * loader/CachedCSSStyleSheet.cpp:
     19        (WebCore::CachedCSSStyleSheet::data):
     20        * loader/CachedCSSStyleSheet.h:
     21        * loader/CachedImage.cpp:
     22        (WebCore::CachedImage::data):
     23        * loader/CachedImage.h:
     24        * loader/CachedResource.cpp:
     25        (WebCore::CachedResource::CachedResource):
     26        (WebCore::CachedResource::~CachedResource):
     27        * loader/CachedResource.h:
     28        (WebCore::CachedResource::data):
     29        * loader/CachedScript.cpp:
     30        (WebCore::CachedScript::data):
     31        * loader/CachedScript.h:
     32        * loader/CachedXSLStyleSheet.cpp:
     33        (WebCore::CachedXSLStyleSheet::data):
     34        * loader/CachedXSLStyleSheet.h:
     35        * loader/DocLoader.cpp:
     36        (WebCore::DocLoader::checkCacheObjectStatus):
     37        * loader/ImageDocument.cpp:
     38        (WebCore::ImageTokenizer::writeRawData):
     39        (WebCore::ImageTokenizer::finish):
     40        * loader/icon/IconDataCache.cpp:
     41        (WebCore::IconDataCache::setImageData):
     42        (WebCore::IconDataCache::writeToDatabase):
     43        * loader/icon/IconDataCache.h:
     44        * loader/icon/IconDatabase.cpp:
     45        (WebCore::IconDatabase::imageDataForIconURL):
     46        (WebCore::IconDatabase::iconForPageURL):
     47        (WebCore::IconDatabase::setIconDataForIconURL):
     48        (WebCore::IconDatabase::setHaveNoIconForIconURL):
     49        (WebCore::IconDatabase::imageDataForIconURLQuery):
     50        * loader/icon/IconDatabase.h:
     51        * loader/icon/IconLoader.cpp:
     52        (WebCore::IconLoader::startLoading):
     53        (WebCore::IconLoader::didReceiveResponse):
     54        (WebCore::IconLoader::didReceiveData):
     55        (WebCore::IconLoader::didFail):
     56        (WebCore::IconLoader::finishLoading):
     57        (WebCore::IconLoader::clearLoadingState):
     58        * loader/icon/IconLoader.h:
     59        * loader/icon/SQLStatement.cpp:
     60        (WebCore::SQLStatement::getColumnBlobAsVector):
     61        (WebCore::SQLStatement::isExpired):
     62        * loader/icon/SQLStatement.h:
     63        * loader/loader.cpp:
     64        (WebCore::Loader::didFinishLoading):
     65        (WebCore::Loader::didReceiveData):
     66        * page/mac/WebCoreFrameBridge.mm:
     67        (-[WebCoreFrameBridge getData:andResponse:forURL:]):
     68        (-[WebCoreFrameBridge getAllResourceDatas:andResponses:]):
     69        * platform/SharedBuffer.h:
     70        (WebCore::SharedBuffer::isEmpty):
     71        * platform/graphics/BitmapImage.cpp:
     72        (WebCore::BitmapImage::destroyDecodedData):
     73        (WebCore::BitmapImage::dataChanged):
     74        * platform/graphics/BitmapImage.h:
     75        * platform/graphics/Image.cpp:
     76        (WebCore::Image::setData):
     77        * platform/graphics/Image.h:
     78        (WebCore::Image::dataChanged):
     79        (WebCore::Image::data):
     80        * platform/graphics/ImageSource.h:
     81        * platform/graphics/cg/ImageSourceCG.cpp:
     82        (WebCore::ImageSource::setData):
     83        * platform/graphics/cg/PDFDocumentImage.cpp:
     84        (WebCore::PDFDocumentImage::dataChanged):
     85        * platform/graphics/cg/PDFDocumentImage.h:
     86        * platform/graphics/mac/ImageMac.mm:
     87        (WebCore::Image::loadPlatformResource):
     88        * platform/graphics/svg/SVGImage.cpp:
     89        (WebCore::SVGImage::setData):
     90        * platform/mac/PasteboardMac.mm:
     91        (WebCore::fileWrapperForImage):
     92
    1932007-03-13  Justin Garcia  <justin.garcia@apple.com>
    294
  • trunk/WebCore/WebCore.exp

    r20173 r20182  
    220220__ZN7WebCore12IconDatabase20setIconURLForPageURLERKNS_6StringES3_
    221221__ZN7WebCore12IconDatabase21releaseIconForPageURLERKNS_6StringE
    222 __ZN7WebCore12IconDatabase21setIconDataForIconURLEPKviRKNS_6StringE
     222__ZN7WebCore12IconDatabase21setIconDataForIconURLEN3WTF10PassRefPtrINS_12SharedBufferEEERKNS_6StringE
    223223__ZN7WebCore12IconDatabase23defaultDatabaseFilenameEv
    224224__ZN7WebCore12IconDatabase23isIconExpiredForIconURLERKNS_6StringE
  • trunk/WebCore/loader/CachedCSSStyleSheet.cpp

    r20009 r20182  
    6868}
    6969
    70 void CachedCSSStyleSheet::data(Vector<char>& data, bool allDataReceived)
     70void CachedCSSStyleSheet::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
    7171{
    7272    if (!allDataReceived)
    7373        return;
    7474
    75     setEncodedSize(data.size());
    76     m_sheet = m_decoder->decode(data.data(), encodedSize());
     75    m_data = data;
     76    setEncodedSize(m_data.get() ? m_data->size() : 0);
     77    if (!m_data.get())
     78        return;
     79
     80    m_sheet = m_decoder->decode(m_data->data(), encodedSize());
    7781    m_sheet += m_decoder->flush();
    7882    m_loading = false;
  • trunk/WebCore/loader/CachedCSSStyleSheet.h

    r19977 r20182  
    4848 
    4949        virtual void setEncoding(const String&);
    50         virtual void data(Vector<char>&, bool allDataReceived);
     50        virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
    5151        virtual void error();
    5252
  • trunk/WebCore/loader/CachedImage.cpp

    r20165 r20182  
    166166}
    167167
    168 Vector<char>& CachedImage::bufferData(const char* bytes, int addedSize, Request* request)
    169 {
    170     createImage();
    171 
    172     Vector<char>& imageBuffer = m_image->dataBuffer();
    173 
    174     if (addedSize > 0) {
    175         bool success = false;
    176         unsigned oldSize = imageBuffer.size();
    177         unsigned newSize = oldSize + addedSize;
    178 
    179         // Check for overflow
    180         if (newSize > oldSize) {
    181             // Use temporary Vector so we can safely detect if the allocation fails
    182             //
    183             // The code that was here before, just called resize of the imageBuffer.  Vector<>::resize
    184             // will crash if the resize of a non-empty Vector<> fails.
    185             Vector<char> tempBuffer(newSize);
    186 
    187             char* tempBufferBytes = tempBuffer.data();
    188             if (tempBufferBytes) {
    189                 memcpy(tempBufferBytes, imageBuffer.data(), oldSize);
    190                 memcpy(tempBufferBytes + oldSize, bytes, addedSize);
    191                 tempBuffer.swap(imageBuffer);
    192                 success = true;
    193             }
    194         }
    195 
    196         if (!success)
    197             error();
    198     }
    199 
    200     return imageBuffer;
    201 }
    202 
    203 void CachedImage::data(Vector<char>& data, bool allDataReceived)
    204 {
     168void CachedImage::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
     169{
     170    m_data = data;
     171
    205172    createImage();
    206173
     
    210177    // It will not do anything now, but will delay decoding until
    211178    // queried for info (like size or specific image frames).
    212     sizeAvailable = m_image->setData(allDataReceived);
     179    sizeAvailable = m_image->setData(m_data, allDataReceived);
    213180
    214181    // Go ahead and tell our observers to try to draw if we have either
     
    227194        notifyObservers();
    228195
    229         if (m_image) {
    230             Vector<char>& imageBuffer = m_image->dataBuffer();
    231 #if PLATFORM(CG)
    232             // ImageIO sources copy the image data.  We will go ahead and count encoded
    233             // size twice until this issue is fixed.  See <rdar://problem/5050645>
    234             setEncodedSize(imageBuffer.size() * 2);
    235 #else
    236             setEncodedSize(imageBuffer.size());
    237 #endif
    238         }
     196        if (m_image)
     197            setEncodedSize(m_image->data() ? m_image->data()->size() : 0);
    239198    }
    240199   
  • trunk/WebCore/loader/CachedImage.h

    r20009 r20182  
    5858    virtual void destroyDecodedData();
    5959
    60     virtual Vector<char>& bufferData(const char* bytes, int addedSize, Request*);
    61     virtual void data(Vector<char>&, bool allDataReceived);
     60    virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
    6261    virtual void error();
    6362
     
    8483
    8584    Image* m_image;
    86     int m_dataSize;
    8785
    8886    friend class Cache;
  • trunk/WebCore/loader/CachedResource.cpp

    r20163 r20182  
    4747    m_cachePolicy = cachePolicy;
    4848    m_request = 0;
    49     m_allData = 0;
    5049    m_expireDateChanged = false;
    5150    m_accessCount = 0;
     
    6766    m_deleted = true;
    6867#endif
    69     setAllData(0);
    70 }
    71 
    72 Vector<char>& CachedResource::bufferData(const char* bytes, int addedSize, Request* request)
    73 {
    74     // Add new bytes to the buffer in the Request object.
    75     Vector<char>& buffer = request->buffer();
    76 
    77     unsigned oldSize = buffer.size();
    78     buffer.resize(oldSize + addedSize);
    79     memcpy(buffer.data() + oldSize, bytes, addedSize);
    80    
    81     return buffer;
    8268}
    8369
  • trunk/WebCore/loader/CachedResource.h

    r20009 r20182  
    7272
    7373    virtual void setEncoding(const String&) { }
    74     virtual Vector<char>& bufferData(const char* bytes, int addedSize, Request*);
    75     virtual void data(Vector<char>&, bool allDataReceived) = 0;
     74    virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived) = 0;
    7675    virtual void error() = 0;
    7776
     
    114113    void setRequest(Request*);
    115114
    116     SharedBuffer* allData() const { return m_allData.get(); }
    117     void setAllData(PassRefPtr<SharedBuffer> allData) { m_allData = allData; }
     115    SharedBuffer* data() const { return m_data.get(); }
    118116
    119117    void setResponse(const ResourceResponse& response) { m_response = response; }
     
    146144
    147145    ResourceResponse m_response;
    148     RefPtr<SharedBuffer> m_allData;
     146    RefPtr<SharedBuffer> m_data;
    149147
    150148    Type m_type;
  • trunk/WebCore/loader/CachedScript.cpp

    r20009 r20182  
    7171}
    7272
    73 void CachedScript::data(Vector<char>& data, bool allDataReceived)
     73void CachedScript::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
    7474{
    75     if (!allDataReceived)
     75    if (!allDataReceived || !data.get())
    7676        return;
    7777
    78     setEncodedSize(data.size());
    79     m_script = m_encoding.decode(data.data(), encodedSize());
     78    m_data = data;
     79    setEncodedSize(m_data.get() ? m_data->size() : 0);
     80    if (!m_data.get())
     81        return;
     82    m_script = m_encoding.decode(m_data->data(), encodedSize());
    8083    m_loading = false;
    8184    checkNotify();
  • trunk/WebCore/loader/CachedScript.h

    r19952 r20182  
    4646
    4747        virtual void setEncoding(const String&);
    48         virtual void data(Vector<char>&, bool allDataReceived);
     48        virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
    4949        virtual void error();
    5050
  • trunk/WebCore/loader/CachedXSLStyleSheet.cpp

    r20009 r20182  
    6767}
    6868
    69 void CachedXSLStyleSheet::data(Vector<char>& data, bool allDataReceived)
     69void CachedXSLStyleSheet::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
    7070{
    71     if (!allDataReceived)
     71    if (!allDataReceived || !data.get())
    7272        return;
    7373
    74     setEncodedSize(data.size());
    75     m_sheet = String(m_decoder->decode(data.data(), encodedSize()));
     74    m_data = data;     
     75    setEncodedSize(m_data.get() ? m_data->size() : 0);
     76    if (!m_data.get())
     77        return;
     78    m_sheet = String(m_decoder->decode(m_data->data(), encodedSize()));
    7679    m_sheet += m_decoder->flush();
    7780    m_loading = false;
  • trunk/WebCore/loader/CachedXSLStyleSheet.h

    r19855 r20182  
    4747       
    4848        virtual void setEncoding(const String&);
    49         virtual void data(Vector<char>&, bool allDataReceived);
     49        virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
    5050        virtual void error();
    5151       
  • trunk/WebCore/loader/DocLoader.cpp

    r19977 r20182  
    203203    ResourceRequest request(resource->url());
    204204    const ResourceResponse& response = resource->response();
    205     SharedBuffer* data = resource->allData();
     205    SharedBuffer* data = resource->data();
    206206   
    207207    // FIXME: If the WebKit client changes or cancels the request, WebCore does not respect this and continues the load.
  • trunk/WebCore/loader/ImageDocument.cpp

    r19737 r20182  
    9797
    9898    CachedImage* cachedImage = m_imageElement->cachedImage();
    99     cachedImage->data(cachedImage->bufferData(data, len, 0), false);
     99    cachedImage->data(m_doc->frame()->loader()->documentLoader()->mainResourceData(), false);
    100100
    101101    return false;
     
    113113    if (!m_parserStopped && m_imageElement) {
    114114        CachedImage* cachedImage = m_imageElement->cachedImage();
    115         Vector<char>& buffer = cachedImage->bufferData(0, 0, 0);
    116         cachedImage->data(buffer, true);
     115        cachedImage->data(m_doc->frame()->loader()->documentLoader()->mainResourceData(), true);
    117116        cachedImage->finish();
    118117
    119         cachedImage->setAllData(m_doc->frame()->loader()->documentLoader()->mainResourceData());
    120118        cachedImage->setResponse(m_doc->frame()->loader()->documentLoader()->response());
    121119       
  • trunk/WebCore/loader/icon/IconDataCache.cpp

    r18446 r20182  
    6161}
    6262
    63 void IconDataCache::setImageData(unsigned char* data, int size)
     63void IconDataCache::setImageData(PassRefPtr<SharedBuffer> data)
    6464{
    65     if (!data)
    66         ASSERT(!size);
    67 
    6865    // It's okay to delete the raw image data here. Any existing clients using this icon will be
    6966    // managing an image that was created with a copy of this raw image data.
     
    7269    m_image = new BitmapImage();
    7370
    74     // Copy the provided data into the buffer of the new Image object
    75     Vector<char>& dataBuffer = m_image->dataBuffer();
    76     dataBuffer.resize(size);
    77     memcpy(dataBuffer.data(), data, size);
    78    
    79     // Tell the Image object that all of its data has been set
    80     if (!m_image->setData(true)) {
     71    // Copy the provided data into the buffer of the new Image object.
     72    if (!m_image->setData(data, true)) {
    8173        LOG(IconDatabase, "Manual image data for iconURL '%s' FAILED - it was probably invalid image data", m_iconURL.ascii().data());
    8274        delete m_image;
     
    120112    // If we *have* image data, bind it to this statement - Otherwise the DB will get "null" for the blob data,
    121113    // signifying that this icon doesn't have any data   
    122     if (m_image && !m_image->dataBuffer().isEmpty())
    123         if (updateAttempt.bindBlob(2, m_image->dataBuffer().data(), m_image->dataBuffer().size()) != SQLResultOk) {
     114    if (m_image && !m_image->data()->isEmpty())
     115        if (updateAttempt.bindBlob(2, m_image->data()->data(), m_image->data()->size()) != SQLResultOk) {
    124116            LOG_ERROR("Failed to bind icon data to SQL statement to update icon data for url %s", m_iconURL.ascii().data());
    125117            return;
     
    147139    // Then, if we *have* data, we bind it.  Otherwise the DB will get "null" for the blob data,
    148140    // signifying that this icon doesn't have any data
    149     if (m_image && !m_image->dataBuffer().isEmpty())
    150         insertStatement.bindBlob(3, m_image->dataBuffer().data(), m_image->dataBuffer().size());
     141    if (m_image && !m_image->data()->isEmpty())
     142        insertStatement.bindBlob(3, m_image->data()->data(), m_image->data()->size());
    151143   
    152144    // Finally we step and make sure the step was successful
  • trunk/WebCore/loader/icon/IconDataCache.h

    r18874 r20182  
    3333class Image;
    3434class IntSize;
     35class SharedBuffer;
    3536class SQLDatabase;
    3637
     
    5051    String getIconURL() { return m_iconURL; }
    5152
    52     void setImageData(unsigned char* data, int size);
     53    void setImageData(PassRefPtr<SharedBuffer> data);
    5354   
    5455    void loadImageFromResource(const char*);
  • trunk/WebCore/loader/icon/IconDatabase.cpp

    r17704 r20182  
    321321}   
    322322
    323 void IconDatabase::imageDataForIconURL(const String& iconURL, Vector<unsigned char>& result)
     323void IconDatabase::imageDataForIconURL(const String& iconURL, PassRefPtr<SharedBuffer> result)
    324324{     
    325325    // If private browsing is enabled, we'll check there first as the most up-to-date data for an icon will be there
    326326    if (m_privateBrowsingEnabled) {   
    327327        imageDataForIconURLQuery(m_privateBrowsingDB, iconURL, result);
    328         if (!result.isEmpty())
     328        if (!result->isEmpty())
    329329            return;
    330330    }
     
    371371    // we'll read in that image data now
    372372    if (icon->imageDataStatus() == ImageDataStatusUnknown) {
    373         Vector<unsigned char> data;
    374         imageDataForIconURL(iconURL, data);
    375         icon->setImageData(data.data(), data.size());
     373        RefPtr<SharedBuffer> data = new SharedBuffer();
     374        imageDataForIconURL(iconURL, data.get());
     375        icon->setImageData(data.get());
    376376    }
    377377       
     
    641641}
    642642
    643 void IconDatabase::setIconDataForIconURL(const void* data, int size, const String& iconURL)
    644 {
    645     ASSERT(size > -1);
     643void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL)
     644{
    646645    if (!isOpen() || iconURL.isEmpty())
    647646        return;
    648647
    649     if (size)
    650         ASSERT(data);
    651     else
    652         data = 0;
    653    
    654648    // Get the IconDataCache for this IconURL (note, IconDataCacheForIconURL will create it if necessary)
    655649    IconDataCache* icon = getOrCreateIconDataCache(iconURL);
    656650   
    657651    // Set the data in the IconDataCache
    658     icon->setImageData((unsigned char*)data, size);
     652    icon->setImageData(data);
    659653   
    660654    // Update the timestamp in the IconDataCache to NOW
     
    667661void IconDatabase::setHaveNoIconForIconURL(const String& iconURL)
    668662{   
    669     setIconDataForIconURL(0, 0, iconURL);
     663    setIconDataForIconURL(0, iconURL);
    670664}
    671665
     
    956950}
    957951
    958 void IconDatabase::imageDataForIconURLQuery(SQLDatabase& db, const String& iconURL, Vector<unsigned char>& imageData)
     952void IconDatabase::imageDataForIconURLQuery(SQLDatabase& db, const String& iconURL, PassRefPtr<SharedBuffer> imageData)
    959953{
    960954    readySQLStatement(m_imageDataForIconURLStatement, db, "SELECT Icon.data FROM Icon WHERE Icon.url = (?);");
     
    962956   
    963957    int result = m_imageDataForIconURLStatement->step();
    964     imageData.clear();
    965     if (result == SQLResultRow)
    966         m_imageDataForIconURLStatement->getColumnBlobAsVector(0, imageData);
    967     else if (result != SQLResultDone)
     958    imageData->clear();
     959    if (result == SQLResultRow) {
     960        Vector<char> data;
     961        m_imageDataForIconURLStatement->getColumnBlobAsVector(0, data);
     962        imageData->append(data.data(), data.size());
     963    } else if (result != SQLResultDone)
    968964        LOG_ERROR("imageDataForIconURLQuery failed");
    969965
  • trunk/WebCore/loader/icon/IconDatabase.h

    r18874 r20182  
    3939class IntSize;
    4040class IconDataCache;
     41class SharedBuffer;
    4142class SQLTransaction;
    4243
     
    6869    bool isIconExpiredForIconURL(const String&);
    6970   
    70     void setIconDataForIconURL(const void* data, int size, const String&);
     71    void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
    7172    void setHaveNoIconForIconURL(const String&);
    7273   
     
    122123   
    123124    // Returns the image data for the given IconURL, checking both databases if necessary
    124     void imageDataForIconURL(const String& iconURL, Vector<unsigned char>&);
     125    void imageDataForIconURL(const String& iconURL, PassRefPtr<SharedBuffer> result);
    125126   
    126127    // Retains an iconURL, bringing it back from the brink if it was pending deletion
     
    162163   
    163164    // Query - Returns the image data from the given database for the given IconURL
    164     void imageDataForIconURLQuery(SQLDatabase& db, const String& iconURL, Vector<unsigned char>& result);
     165    void imageDataForIconURLQuery(SQLDatabase& db, const String& iconURL, PassRefPtr<SharedBuffer> result);
    165166    SQLStatement* m_imageDataForIconURLStatement;
    166167
  • trunk/WebCore/loader/icon/IconLoader.cpp

    r18047 r20182  
    4242namespace WebCore {
    4343
    44 const size_t defaultBufferSize = 4096; // bigger than most icons
    45 
    4644IconLoader::IconLoader(Frame* frame)
    4745    : m_frame(frame)
     
    7573    // SubresourceLoader::create returns.
    7674    m_loadIsInProgress = true;
    77     m_buffer.reserveCapacity(defaultBufferSize);
    7875
    7976    RefPtr<SubresourceLoader> loader = SubresourceLoader::create(m_frame, this, m_frame->loader()->iconURL());
     
    10097    if (status && (status < 200 || status > 299)) {
    10198        KURL iconURL = resourceLoader->handle()->url();
     99        finishLoading(iconURL);
    102100        m_resourceLoader = 0;
    103         finishLoading(iconURL);
    104101    }
    105102}
     
    107104void IconLoader::didReceiveData(SubresourceLoader*, const char* data, int size)
    108105{
    109     ASSERT(data || size == 0);
    110     ASSERT(size >= 0);
    111     m_buffer.append(data, size);
    112106}
    113107
     
    115109{
    116110    ASSERT(m_loadIsInProgress);
    117     m_buffer.clear();
    118111    finishLoading(resourceLoader->handle()->url());
    119112}
     
    131124void IconLoader::finishLoading(const KURL& iconURL)
    132125{
    133     IconDatabase::sharedIconDatabase()->setIconDataForIconURL(m_buffer.data(), m_buffer.size(), iconURL.url());
     126    IconDatabase::sharedIconDatabase()->setIconDataForIconURL(m_resourceLoader->resourceData(), iconURL.url());
    134127    m_frame->loader()->commitIconURLToIconDatabase(iconURL);
    135128    m_frame->loader()->client()->dispatchDidReceiveIcon();
     
    140133{
    141134    m_resourceLoader = 0;
    142     m_buffer.clear();
    143135    m_loadIsInProgress = false;
    144136}
  • trunk/WebCore/loader/icon/IconLoader.h

    r18874 r20182  
    3131#include <memory>
    3232#include <wtf/Noncopyable.h>
    33 #include <wtf/Vector.h>
    3433
    3534namespace WebCore {
     
    5958
    6059    RefPtr<SubresourceLoader> m_resourceLoader;
    61     Vector<char> m_buffer;
    6260    bool m_loadIsInProgress;
    6361}; // class IconLoader
  • trunk/WebCore/loader/icon/SQLStatement.cpp

    r16595 r20182  
    231231}
    232232   
    233 void SQLStatement::getColumnBlobAsVector(int col, Vector<unsigned char>& result)
     233void SQLStatement::getColumnBlobAsVector(int col, Vector<char>& result)
    234234{
    235235    if (!m_statement && prepareAndStep() != SQLITE_ROW) {
  • trunk/WebCore/loader/icon/SQLStatement.h

    r18874 r20182  
    8080    int64_t getColumnInt64(int col);
    8181    const void* getColumnBlob(int col, int& size);
    82     void getColumnBlobAsVector(int col, Vector<unsigned char>&);
     82    void getColumnBlobAsVector(int col, Vector<char>&);
    8383
    8484    bool returnTextResults(int col, Vector<String>&);
  • trunk/WebCore/loader/loader.cpp

    r20178 r20182  
    105105
    106106    docLoader->setLoadInProgress(true);
    107     object->data(req->buffer(), true);
    108     object->setAllData(loader->resourceData());
     107    object->data(loader->resourceData(), true);
    109108    docLoader->setLoadInProgress(false);
    110109    object->finish();
     
    168167
    169168    CachedResource* object = request->cachedResource();   
    170     Vector<char>& buffer = object->bufferData(data, size, request);
    171169
    172170    // Set the data.
    173171    if (request->isMultipart())
    174172        // The loader delivers the data in a multipart section all at once, send eof.
    175         object->data(buffer, true);
     173        object->data(loader->resourceData(), true);
    176174    else if (request->isIncremental())
    177         object->data(buffer, false);
     175        object->data(loader->resourceData(), false);
    178176}
    179177
  • trunk/WebCore/page/mac/WebCoreFrameBridge.mm

    r20180 r20182  
    14091409        return NO;
    14101410
    1411     SharedBuffer* buffer = resource->allData();
     1411    SharedBuffer* buffer = resource->data();
    14121412    if (buffer)
    14131413        *data = [buffer->createNSData() autorelease];
     
    14361436    HashMap<String, CachedResource*>::const_iterator end = allResources.end();
    14371437    for (HashMap<String, CachedResource*>::const_iterator it = allResources.begin(); it != end; ++it) {
    1438         SharedBuffer* buffer = it->second->allData();
     1438        SharedBuffer* buffer = it->second->data();
    14391439        NSData *data;
    14401440       
  • trunk/WebCore/platform/SharedBuffer.h

    r19764 r20182  
    5555    unsigned size() const;
    5656
     57    bool isEmpty() const { return size() == 0; }
     58
    5759    void append(const char*, int);
    5860    void clear();
  • trunk/WebCore/platform/graphics/BitmapImage.cpp

    r20169 r20182  
    9595            // while animating that it seems to never clear.
    9696            m_source.clear();
    97             setData(true);
     97            dataChanged(true);
    9898        }
    9999    }
     
    138138}
    139139
    140 bool BitmapImage::setNativeData(NativeBytePtr data, bool allDataReceived)
     140bool BitmapImage::dataChanged(bool allDataReceived)
    141141{
    142142    destroyDecodedData(true);
    143143   
    144144    // Feed all the data we've seen so far to the image decoder.
    145     m_source.setData(data, allDataReceived);
     145    m_source.setData(m_data.get(), allDataReceived);
    146146   
    147147    // Image properties will not be available until the first frame of the file
  • trunk/WebCore/platform/graphics/BitmapImage.h

    r20009 r20182  
    9595    virtual IntSize size() const;
    9696
    97     virtual bool setNativeData(NativeBytePtr, bool allDataReceived);
     97    virtual bool dataChanged(bool allDataReceived);
    9898
    9999    // It may look unusual that there is no start animation call as public API.  This is because
  • trunk/WebCore/platform/graphics/Image.cpp

    r20009 r20182  
    6060}
    6161
    62 bool Image::setData(bool allDataReceived)
     62bool Image::setData(PassRefPtr<SharedBuffer> data, bool allDataReceived)
    6363{
    64     int length = m_data.size();
     64    m_data = data;
     65    if (!m_data.get())
     66        return true;
     67
     68    int length = m_data->size();
    6569    if (!length)
    6670        return true;
     
    7680#endif
    7781   
    78 #if PLATFORM(CG)
    79     // Avoid the extra copy of bytes by just handing the byte array directly to a CFDataRef.
    80     CFDataRef data = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(m_data.data()), length, kCFAllocatorNull);
    81     bool result = setNativeData(data, allDataReceived);
    82     CFRelease(data);
    83 #else
    84     bool result = setNativeData(&m_data, allDataReceived);
    85 #endif
    86 
    87     return result;
     82    return dataChanged(allDataReceived);
    8883}
    8984
  • trunk/WebCore/platform/graphics/Image.h

    r20044 r20182  
    3131#include "GraphicsTypes.h"
    3232#include "ImageSource.h"
     33#include <wtf/RefPtr.h>
     34#include <wtf/PassRefPtr.h>
     35#include "SharedBuffer.h"
    3336
    3437#if PLATFORM(MAC)
     
    6164class IntRect;
    6265class IntSize;
     66class SharedBuffer;
    6367class String;
    6468
     
    8286    int height() const;
    8387
    84     virtual bool setData(bool allDataReceived);
    85     virtual bool setNativeData(NativeBytePtr, bool allDataReceived) { return false; }
     88    bool setData(PassRefPtr<SharedBuffer> data, bool allDataReceived);
     89    virtual bool dataChanged(bool allDataReceived) { return false; }
    8690   
    8791    // FIXME: PDF/SVG will be underreporting decoded sizes and will be unable to prune because these functions are not
     
    9094    virtual unsigned decodedSize() const { return 0; }
    9195
    92     Vector<char>& dataBuffer() { return m_data; }
     96    SharedBuffer* data() { return m_data.get(); }
    9397
    9498    // It may look unusual that there is no start animation call as public API.  This is because
     
    146150   
    147151protected:
    148     Vector<char> m_data; // The encoded raw data for the image.
     152    RefPtr<SharedBuffer> m_data; // The encoded raw data for the image.
    149153    ImageObserver* m_imageObserver;
    150154};
  • trunk/WebCore/platform/graphics/ImageSource.h

    r20070 r20182  
    4444
    4545class IntSize;
     46class SharedBuffer;
    4647
    4748#if PLATFORM(CG)
    4849typedef CGImageSourceRef NativeImageSourcePtr;
    4950typedef CGImageRef NativeImagePtr;
    50 typedef CFDataRef NativeBytePtr;
    5151#elif PLATFORM(QT)
    5252class ImageDecoderQt;
    5353typedef ImageDecoderQt* NativeImageSourcePtr;
    54 typedef const Vector<char>* NativeBytePtr;
    5554typedef QPixmap* NativeImagePtr;
    5655#else
    5756class ImageDecoder;
    5857typedef ImageDecoder* NativeImageSourcePtr;
    59 typedef const Vector<char>* NativeBytePtr;
    6058typedef cairo_surface_t* NativeImagePtr;
    6159#endif
     
    7371    bool initialized() const;
    7472   
    75     void setData(NativeBytePtr, bool allDataReceived);
     73    void setData(SharedBuffer* data, bool allDataReceived);
    7674
    7775    bool isSizeAvailable();
  • trunk/WebCore/platform/graphics/cg/ImageSourceCG.cpp

    r20070 r20182  
    2626#include "config.h"
    2727#include "ImageSource.h"
     28#include "SharedBuffer.h"
    2829
    2930#if PLATFORM(CG)
     
    7273}
    7374
    74 void ImageSource::setData(NativeBytePtr data, bool allDataReceived)
     75void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
    7576{
    7677    if (!m_decoder)
    7778        m_decoder = CGImageSourceCreateIncremental(NULL);
    78     CGImageSourceUpdateData(m_decoder, data, allDataReceived);
     79       
     80    CFDataRef cfData = (CFDataRef)data->createNSData();
     81    CGImageSourceUpdateData(m_decoder, cfData, allDataReceived);
     82    CFRelease(cfData);
    7983}
    8084
  • trunk/WebCore/platform/graphics/cg/PDFDocumentImage.cpp

    r18904 r20182  
    5454}
    5555
    56 bool PDFDocumentImage::setNativeData(NativeBytePtr data, bool allDataReceived)
     56bool PDFDocumentImage::dataChanged(bool allDataReceived)
    5757{
    58     if (allDataReceived && !m_document && data) {
     58    if (allDataReceived && !m_document) {
     59        CFDataRef data = (CFDataRef)m_data->createNSData();
    5960        CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);
     61        CFRelease(data);
    6062        m_document = CGPDFDocumentCreateWithProvider(dataProvider);
    6163        CGDataProviderRelease(dataProvider);
  • trunk/WebCore/platform/graphics/cg/PDFDocumentImage.h

    r18904 r20182  
    4242        ~PDFDocumentImage();
    4343       
    44         virtual bool setNativeData(NativeBytePtr, bool allDataReceived);
     44        virtual bool dataChanged(bool allDataReceived);
    4545
    4646        virtual IntSize size() const;
  • trunk/WebCore/platform/graphics/mac/ImageMac.mm

    r18446 r20182  
    6565    if (namedImageData) {
    6666        Image* image = new BitmapImage;
    67         image->setNativeData((CFDataRef)namedImageData, true);
     67        image->setData(SharedBuffer::wrapNSData(namedImageData), true);
    6868        return image;
    6969    }
  • trunk/WebCore/platform/graphics/svg/SVGImage.cpp

    r20009 r20182  
    119119}
    120120
    121 bool SVGImage::setData(bool allDataReceived)
     121bool SVGImage::dataChanged(bool allDataReceived)
    122122{
    123     int length = dataBuffer().size();
     123    int length = m_data->size();
    124124    if (!length) // if this was an empty image
    125125        return true;
     
    147147        m_frame->loader()->setResponseMIMEType("image/svg+xml");
    148148        m_frame->loader()->begin("placeholder.svg"); // create the empty document
    149         m_frame->loader()->write(dataBuffer().data(), dataBuffer().size());
     149        m_frame->loader()->write(m_data->data(), m_data->size());
    150150        m_frame->loader()->end();
    151151    }
  • trunk/WebCore/platform/graphics/svg/SVGImage.h

    r20009 r20182  
    4848        virtual IntSize size() const;
    4949       
    50         virtual bool setData(bool allDataReceived);
    51        
     50        virtual bool dataChanged(bool allDataReceived);
     51
    5252        virtual NativeImagePtr frameAtIndex(size_t) { return 0; }
    5353       
  • trunk/WebCore/platform/mac/PasteboardMac.mm

    r20130 r20182  
    248248static NSFileWrapper* fileWrapperForImage(CachedResource* resource, NSURL *URL)
    249249{
    250     SharedBuffer* coreData = resource->allData();
     250    SharedBuffer* coreData = resource->data();
    251251    NSData *data = [[[NSData alloc] initWithBytes:coreData->platformData()
    252252        length:coreData->platformDataSize()] autorelease];
  • trunk/WebKit/ChangeLog

    r20180 r20182  
     12007-03-14  David Hyatt  <hyatt@apple.com>
     2
     3        Fixes to ensure that the resource loader's shared buffer can always be used.
     4
     5        Reviewed by olliej, mjs
     6
     7        * Misc/WebIconDatabase.mm:
     8        (-[WebIconDatabase _convertToWebCoreFormat]):
     9        * WebCoreSupport/WebFrameLoaderClient.mm:
     10        (WebFrameLoaderClient::deliverArchivedResources):
     11
    1122007-03-13  Oliver Hunt  <oliver@apple.com>
    213
  • trunk/WebKit/Misc/WebIconDatabase.mm

    r19921 r20182  
    530530        iconData = iconDataFromPathForIconURL(databaseDirectory, url);
    531531        if (iconData)
    532             IconDatabase::sharedIconDatabase()->setIconDataForIconURL([iconData bytes], [iconData length], url);
     532            IconDatabase::sharedIconDatabase()->setIconDataForIconURL(SharedBuffer::wrapNSData(iconData), url);
    533533        else {
    534534            // This really *shouldn't* happen, so it'd be good to track down why it might happen in a debug build
  • trunk/WebKit/WebCoreSupport/WebFrameLoaderClient.mm

    r20173 r20182  
    950950        NSData *data = [[resource data] retain];
    951951        loader->didReceiveResponse([resource _response]);
     952        loader->addData((const char*)[data bytes], [data length], true);
    952953        loader->didReceiveData((const char*)[data bytes], [data length], [data length], true);
    953954        [data release];
Note: See TracChangeset for help on using the changeset viewer.