Cache function offsets to speed up javascript parsing
[WebKit.git] / Source / WebCore / loader / cache / CachedScript.cpp
1 /*
2     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3     Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4     Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5     Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6     Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Library General Public
10     License as published by the Free Software Foundation; either
11     version 2 of the License, or (at your option) any later version.
12
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Library General Public License for more details.
17
18     You should have received a copy of the GNU Library General Public License
19     along with this library; see the file COPYING.LIB.  If not, write to
20     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21     Boston, MA 02110-1301, USA.
22
23     This class provides all functionality needed for loading images, style sheets and html
24     pages from the web. It has a memory cache for these objects.
25 */
26
27 #include "config.h"
28 #include "CachedScript.h"
29
30 #include "MemoryCache.h"
31 #include "CachedResourceClient.h"
32 #include "CachedResourceClientWalker.h"
33 #include "SharedBuffer.h"
34 #include "TextResourceDecoder.h"
35 #include <wtf/Vector.h>
36
37 #if USE(JSC)  
38 #include <parser/SourceProvider.h>
39 #endif
40
41 namespace WebCore {
42
43 CachedScript::CachedScript(const String& url, const String& charset)
44     : CachedResource(url, Script)
45     , m_decoder(TextResourceDecoder::create("application/javascript", charset))
46     , m_decodedDataDeletionTimer(this, &CachedScript::decodedDataDeletionTimerFired)
47 {
48     // It's javascript we want.
49     // But some websites think their scripts are <some wrong mimetype here>
50     // and refuse to serve them if we only accept application/x-javascript.
51     setAccept("*/*");
52 }
53
54 CachedScript::~CachedScript()
55 {
56 }
57
58 void CachedScript::allClientsRemoved()
59 {
60     m_decodedDataDeletionTimer.startOneShot(0);
61 }
62
63 void CachedScript::setEncoding(const String& chs)
64 {
65     m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
66 }
67
68 String CachedScript::encoding() const
69 {
70     return m_decoder->encoding().name();
71 }
72
73 const String& CachedScript::script()
74 {
75     ASSERT(!isPurgeable());
76
77     if (!m_script && m_data) {
78         m_script = m_decoder->decode(m_data->data(), encodedSize());
79         m_script += m_decoder->flush();
80         setDecodedSize(m_script.length() * sizeof(UChar));
81     }
82     m_decodedDataDeletionTimer.startOneShot(0);
83     return m_script;
84 }
85
86 void CachedScript::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
87 {
88     if (!allDataReceived)
89         return;
90
91     m_data = data;
92     setEncodedSize(m_data.get() ? m_data->size() : 0);
93     setLoading(false);
94     checkNotify();
95 }
96
97 void CachedScript::checkNotify()
98 {
99     if (isLoading())
100         return;
101
102     CachedResourceClientWalker w(m_clients);
103     while (CachedResourceClient* c = w.next())
104         c->notifyFinished(this);
105 }
106
107 void CachedScript::error(CachedResource::Status status)
108 {
109     setStatus(status);
110     ASSERT(errorOccurred());
111     setLoading(false);
112     checkNotify();
113 }
114
115 void CachedScript::destroyDecodedData()
116 {
117     m_script = String();
118     unsigned extraSize = 0;
119 #if USE(JSC)
120     // FIXME: SourceInfoCache should be wiped out too but not this easily.
121     extraSize = m_sourceProviderCache ? m_sourceProviderCache->byteSize() : 0;
122 #endif
123     setDecodedSize(extraSize);
124     if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
125         makePurgeable(true);
126 }
127
128 void CachedScript::decodedDataDeletionTimerFired(Timer<CachedScript>*)
129 {
130     destroyDecodedData();
131 }
132
133 #if USE(JSC)
134 JSC::SourceProviderCache* CachedScript::sourceProviderCache() const
135 {   
136     if (!m_sourceProviderCache) 
137         m_sourceProviderCache = adoptPtr(new JSC::SourceProviderCache); 
138     return m_sourceProviderCache.get(); 
139 }
140
141 void CachedScript::sourceProviderCacheSizeChanged(int delta)
142 {
143     setDecodedSize(decodedSize() + delta);
144 }
145 #endif
146
147 } // namespace WebCore