Index: content/renderer/renderer_webstoragearea_impl.cc |
diff --git a/content/renderer/renderer_webstoragearea_impl.cc b/content/renderer/renderer_webstoragearea_impl.cc |
index a7cbfb695653da41a2fcdcf5a5c070848a88c2d3..c065b8b0c67e824b294c9f170d1423f0cea858c3 100644 |
--- a/content/renderer/renderer_webstoragearea_impl.cc |
+++ b/content/renderer/renderer_webstoragearea_impl.cc |
@@ -11,6 +11,7 @@ |
#include "content/common/dom_storage_messages.h" |
#include "content/renderer/render_thread_impl.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebCommon.h" |
#include "webkit/dom_storage/dom_storage_types.h" |
using WebKit::WebString; |
@@ -75,21 +76,75 @@ WebString RendererWebStorageAreaImpl::key(unsigned index) { |
WebString RendererWebStorageAreaImpl::getItem(const WebString& key) { |
NullableString16 value; |
- RenderThreadImpl::current()->Send( |
- new DOMStorageHostMsg_GetItem(connection_id_, key, &value)); |
+ unsigned value_len; |
+ base::SharedMemoryHandle browser_handle = base::SharedMemory::NULLHandle(); |
+ dom_storage::IPC_Flag ipc_flag; |
+ RenderThreadImpl::current()->Send(new DOMStorageHostMsg_GetItem( |
+ connection_id_, key, |
+ reinterpret_cast<int*>(&ipc_flag), |
+ &browser_handle, &value_len, &value)); |
+ if (ipc_flag == dom_storage::SharedMemory) { |
+ base::SharedMemory shared_buf(browser_handle, true); |
+ shared_buf.Map(value_len*sizeof(char16)); |
+ string16 shm_str; |
+ shared_buf.Lock(); |
+ shm_str.append(static_cast<char16*>(shared_buf.memory()), value_len); |
+ shared_buf.Unlock(); |
+ shared_buf.Close(); |
+ value = NullableString16(shm_str, false); |
+ } |
return value; |
} |
void RendererWebStorageAreaImpl::setItem( |
const WebString& key, const WebString& value, const WebURL& url, |
WebStorageArea::Result& result, WebString& old_value_webkit) { |
- if (key.length() + value.length() > dom_storage::kPerAreaQuota) { |
+ size_t value_len = value.length()*sizeof(WebKit::WebUChar); |
+ base::SharedMemoryHandle shared_mem_handle; |
+ if (key.length() + value_len > dom_storage::kPerAreaQuota) { |
result = ResultBlockedByQuota; |
return; |
} |
NullableString16 old_value; |
- RenderThreadImpl::current()->Send(new DOMStorageHostMsg_SetItem( |
- connection_id_, key, value, url, &result, &old_value)); |
+ |
+ if (value_len < dom_storage::kShmEnableThreshold) { |
+ RenderThreadImpl::current()->Send(new DOMStorageHostMsg_SetItem( |
+ connection_id_, key, value, url, &result, &old_value)); |
+ old_value_webkit = old_value; |
+ return; |
+ } |
+ // Try Allocate a shared memory buffer to hold the bulk of data. |
+ // if fail, go through channel |
+#if defined(OS_WIN) |
+ base::SharedMemory shared_buf; |
+ if (!shared_buf.CreateAndMapAnonymous(value_len)) { |
+ RenderThreadImpl::current()->Send(new DOMStorageHostMsg_SetItem( |
+ connection_id_, key, value, url, &result, &old_value)); |
+ old_value_webkit = old_value; |
+ return; |
+ } |
+#elif defined(OS_POSIX) |
+ shared_mem_handle = |
+ content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(value_len); |
+ if (!base::SharedMemory::IsHandleValid(shared_mem_handle)) { |
+ RenderThreadImpl::current()->Send(new DOMStorageHostMsg_SetItem( |
+ connection_id_, key, value, url, &result, &old_value)); |
+ old_value_webkit = old_value; |
+ return; |
+ } |
+ base::SharedMemory shared_buf(shared_mem_handle, false); |
+ shared_buf.Map(value_len); |
+#endif |
+ // Go through shm, Copy the bits into shared memory. |
+ shared_buf.Lock(); |
+ memcpy(shared_buf.memory(), value.data(), value_len); |
+ shared_buf.Unlock(); |
+ // give to process |
+ shared_mem_handle = shared_buf.handle(); |
+ RenderThreadImpl::current()->Send(new DOMStorageHostMsg_SetItemOpt( |
+ connection_id_, key, value.length(), shared_mem_handle, url, |
+ &result, &old_value)); |
+ shared_buf.Close(); |
old_value_webkit = old_value; |
} |