perf: use v8::Local<v8::Object> as the key in ObjectCache (#43519)
* perf: use v8::Object* as direct keys instead of using hash + a linked list * refactor: use v8::Local<v8::Object> as the key
This commit is contained in:
		
					parent
					
						
							
								0467790aee
							
						
					
				
			
			
				commit
				
					
						2d868ecb8d
					
				
			
		
					 2 changed files with 25 additions and 34 deletions
				
			
		| 
						 | 
					@ -12,37 +12,22 @@ namespace electron::api::context_bridge {
 | 
				
			||||||
ObjectCache::ObjectCache() = default;
 | 
					ObjectCache::ObjectCache() = default;
 | 
				
			||||||
ObjectCache::~ObjectCache() = default;
 | 
					ObjectCache::~ObjectCache() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ObjectCache::CacheProxiedObject(v8::Local<v8::Value> from,
 | 
					void ObjectCache::CacheProxiedObject(const v8::Local<v8::Value> from,
 | 
				
			||||||
                                     v8::Local<v8::Value> proxy_value) {
 | 
					                                     v8::Local<v8::Value> proxy_value) {
 | 
				
			||||||
  if (from->IsObject() && !from->IsNullOrUndefined()) {
 | 
					  if (from->IsObject() && !from->IsNullOrUndefined())
 | 
				
			||||||
    auto obj = from.As<v8::Object>();
 | 
					    proxy_map_.insert_or_assign(from.As<v8::Object>(), proxy_value);
 | 
				
			||||||
    int hash = obj->GetIdentityHash();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proxy_map_[hash].emplace_front(from, proxy_value);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
v8::MaybeLocal<v8::Value> ObjectCache::GetCachedProxiedObject(
 | 
					v8::MaybeLocal<v8::Value> ObjectCache::GetCachedProxiedObject(
 | 
				
			||||||
    v8::Local<v8::Value> from) const {
 | 
					    const v8::Local<v8::Value> from) const {
 | 
				
			||||||
  if (!from->IsObject() || from->IsNullOrUndefined())
 | 
					  if (!from->IsObject() || from->IsNullOrUndefined())
 | 
				
			||||||
    return v8::MaybeLocal<v8::Value>();
 | 
					    return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto obj = from.As<v8::Object>();
 | 
					  const auto iter = proxy_map_.find(from.As<v8::Object>());
 | 
				
			||||||
  int hash = obj->GetIdentityHash();
 | 
					  if (iter == proxy_map_.end() || iter->second.IsEmpty())
 | 
				
			||||||
  auto iter = proxy_map_.find(hash);
 | 
					    return {};
 | 
				
			||||||
  if (iter == proxy_map_.end())
 | 
					 | 
				
			||||||
    return v8::MaybeLocal<v8::Value>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto& list = iter->second;
 | 
					  return iter->second;
 | 
				
			||||||
  for (const auto& pair : list) {
 | 
					 | 
				
			||||||
    auto from_cmp = pair.first;
 | 
					 | 
				
			||||||
    if (from_cmp == from) {
 | 
					 | 
				
			||||||
      if (pair.second.IsEmpty())
 | 
					 | 
				
			||||||
        return v8::MaybeLocal<v8::Value>();
 | 
					 | 
				
			||||||
      return pair.second;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return v8::MaybeLocal<v8::Value>();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace electron::api::context_bridge
 | 
					}  // namespace electron::api::context_bridge
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,19 +5,18 @@
 | 
				
			||||||
#ifndef ELECTRON_SHELL_RENDERER_API_CONTEXT_BRIDGE_OBJECT_CACHE_H_
 | 
					#ifndef ELECTRON_SHELL_RENDERER_API_CONTEXT_BRIDGE_OBJECT_CACHE_H_
 | 
				
			||||||
#define ELECTRON_SHELL_RENDERER_API_CONTEXT_BRIDGE_OBJECT_CACHE_H_
 | 
					#define ELECTRON_SHELL_RENDERER_API_CONTEXT_BRIDGE_OBJECT_CACHE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <forward_list>
 | 
					 | 
				
			||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
#include <utility>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "content/public/renderer/render_frame.h"
 | 
					#include "v8/include/v8-local-handle.h"
 | 
				
			||||||
#include "content/public/renderer/render_frame_observer.h"
 | 
					#include "v8/include/v8-object.h"
 | 
				
			||||||
#include "shell/renderer/electron_render_frame_observer.h"
 | 
					 | 
				
			||||||
#include "third_party/blink/public/web/web_local_frame.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace electron::api::context_bridge {
 | 
					namespace electron::api::context_bridge {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ObjectCachePair = std::pair<v8::Local<v8::Value>, v8::Local<v8::Value>>;
 | 
					/**
 | 
				
			||||||
 | 
					 * NB: This is designed for context_bridge. Beware using it elsewhere!
 | 
				
			||||||
 | 
					 * Since it's a v8::Local-to-v8::Local cache, be careful to destroy it
 | 
				
			||||||
 | 
					 * before destroying the HandleScope that keeps the locals alive.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class ObjectCache final {
 | 
					class ObjectCache final {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  ObjectCache();
 | 
					  ObjectCache();
 | 
				
			||||||
| 
						 | 
					@ -29,8 +28,15 @@ class ObjectCache final {
 | 
				
			||||||
      v8::Local<v8::Value> from) const;
 | 
					      v8::Local<v8::Value> from) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  // object_identity ==> [from_value, proxy_value]
 | 
					  struct Hash {
 | 
				
			||||||
  std::unordered_map<int, std::forward_list<ObjectCachePair>> proxy_map_;
 | 
					    std::size_t operator()(const v8::Local<v8::Object>& obj) const {
 | 
				
			||||||
 | 
					      return obj->GetIdentityHash();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // from_object ==> proxy_value
 | 
				
			||||||
 | 
					  std::unordered_map<v8::Local<v8::Object>, v8::Local<v8::Value>, Hash>
 | 
				
			||||||
 | 
					      proxy_map_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace electron::api::context_bridge
 | 
					}  // namespace electron::api::context_bridge
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue