Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / v8 / V8ValueCache.cpp
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "bindings/v8/V8ValueCache.h"
28
29 #include "bindings/v8/V8Binding.h"
30 #include "bindings/v8/V8Utilities.h"
31 #include "wtf/text/StringHash.h"
32
33 namespace WebCore {
34
35 static v8::Local<v8::String> makeExternalString(const String& string, v8::Isolate* isolate)
36 {
37     if (string.is8Bit()) {
38         WebCoreStringResource8* stringResource = new WebCoreStringResource8(string);
39         v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
40         if (newString.IsEmpty())
41             delete stringResource;
42         return newString;
43     }
44
45     WebCoreStringResource16* stringResource = new WebCoreStringResource16(string);
46     v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
47     if (newString.IsEmpty())
48         delete stringResource;
49     return newString;
50 }
51
52 v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate)
53 {
54     if (!stringImpl->length())
55         return v8::String::Empty(isolate);
56
57     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
58     if (!cachedV8String.isEmpty()) {
59         m_lastStringImpl = stringImpl;
60         m_lastV8String = cachedV8String;
61         return cachedV8String.newLocal(isolate);
62     }
63
64     return createStringAndInsertIntoCache(stringImpl, isolate);
65 }
66
67 void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> returnValue, StringImpl* stringImpl)
68 {
69     if (!stringImpl->length()) {
70         returnValue.SetEmptyString();
71         return;
72     }
73
74     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
75     if (!cachedV8String.isEmpty()) {
76         m_lastStringImpl = stringImpl;
77         m_lastV8String = cachedV8String;
78         returnValue.Set(*cachedV8String.persistent());
79         return;
80     }
81
82     returnValue.Set(createStringAndInsertIntoCache(stringImpl, returnValue.GetIsolate()));
83 }
84
85 v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate)
86 {
87     ASSERT(!m_stringCache.contains(stringImpl));
88     ASSERT(stringImpl->length());
89
90     v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate);
91     if (newString.IsEmpty())
92         return newString;
93
94     v8::Persistent<v8::String> wrapper(isolate, newString);
95
96     stringImpl->ref();
97     wrapper.MarkIndependent();
98     wrapper.SetWeak(stringImpl, &setWeakCallback);
99     m_lastV8String = UnsafePersistent<v8::String>(wrapper);
100     m_lastStringImpl = stringImpl;
101     m_stringCache.set(stringImpl, m_lastV8String);
102
103     return newString;
104 }
105
106 void StringCache::setWeakCallback(const v8::WeakCallbackData<v8::String, StringImpl>& data)
107 {
108     StringCache* stringCache = V8PerIsolateData::from(data.GetIsolate())->stringCache();
109     stringCache->m_lastStringImpl = 0;
110     stringCache->m_lastV8String.clear();
111     ASSERT(stringCache->m_stringCache.contains(data.GetParameter()));
112     stringCache->m_stringCache.get(data.GetParameter()).dispose();
113     stringCache->m_stringCache.remove(data.GetParameter());
114     data.GetParameter()->deref();
115 }
116
117 } // namespace WebCore