Upstream version 6.35.121.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 "wtf/text/StringHash.h"
31
32 namespace WebCore {
33
34 static v8::Local<v8::String> makeExternalString(const String& string, v8::Isolate* isolate)
35 {
36     if (string.is8Bit()) {
37         WebCoreStringResource8* stringResource = new WebCoreStringResource8(string);
38         v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
39         if (newString.IsEmpty())
40             delete stringResource;
41         return newString;
42     }
43
44     WebCoreStringResource16* stringResource = new WebCoreStringResource16(string);
45     v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
46     if (newString.IsEmpty())
47         delete stringResource;
48     return newString;
49 }
50
51 v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate)
52 {
53     if (!stringImpl->length())
54         return v8::String::Empty(isolate);
55
56     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
57     if (!cachedV8String.isEmpty()) {
58         m_lastStringImpl = stringImpl;
59         m_lastV8String = cachedV8String;
60         return cachedV8String.newLocal(isolate);
61     }
62
63     return createStringAndInsertIntoCache(stringImpl, isolate);
64 }
65
66 void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> returnValue, StringImpl* stringImpl)
67 {
68     if (!stringImpl->length()) {
69         returnValue.SetEmptyString();
70         return;
71     }
72
73     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
74     if (!cachedV8String.isEmpty()) {
75         m_lastStringImpl = stringImpl;
76         m_lastV8String = cachedV8String;
77         returnValue.Set(*cachedV8String.persistent());
78         return;
79     }
80
81     returnValue.Set(createStringAndInsertIntoCache(stringImpl, returnValue.GetIsolate()));
82 }
83
84 v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate)
85 {
86     ASSERT(!m_stringCache.contains(stringImpl));
87     ASSERT(stringImpl->length());
88
89     v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate);
90     if (newString.IsEmpty())
91         return newString;
92
93     v8::Persistent<v8::String> wrapper(isolate, newString);
94
95     stringImpl->ref();
96     wrapper.MarkIndependent();
97     wrapper.SetWeak(stringImpl, &setWeakCallback);
98     m_lastV8String = UnsafePersistent<v8::String>(wrapper);
99     m_lastStringImpl = stringImpl;
100     m_stringCache.set(stringImpl, m_lastV8String);
101
102     return newString;
103 }
104
105 void StringCache::setWeakCallback(const v8::WeakCallbackData<v8::String, StringImpl>& data)
106 {
107     StringCache* stringCache = V8PerIsolateData::from(data.GetIsolate())->stringCache();
108     stringCache->m_lastStringImpl = nullptr;
109     stringCache->m_lastV8String.clear();
110     ASSERT(stringCache->m_stringCache.contains(data.GetParameter()));
111     stringCache->m_stringCache.get(data.GetParameter()).dispose();
112     stringCache->m_stringCache.remove(data.GetParameter());
113     data.GetParameter()->deref();
114 }
115
116 } // namespace WebCore