Commit 2367439b authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

v8bindings: Refactor v8::Template cache of V8PerIsolateData

Unifies the interface template cache and operation template
cache in V8PerIsolateData into a single v8::Template cache,
which will be used to store any sort of v8::Template, e.g.
IDL interface object's template, IDL namespace object's
template, JS function's template, etc.

This is a step to support IDL namespace.

Bug: 839389
Change-Id: I4130c713665fcb8555ea188f2e582035468ade83
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463092
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818911}
parent d4b46d56
...@@ -269,11 +269,9 @@ v8::MaybeLocal<v8::Value> CreateNamedConstructorFunction( ...@@ -269,11 +269,9 @@ v8::MaybeLocal<v8::Value> CreateNamedConstructorFunction(
return v8::Undefined(isolate); return v8::Undefined(isolate);
} }
// Named constructors are not interface objcets (despite that they're
// pretending so), but we reuse the cache of interface objects, which just
// works because both are V8 function template.
v8::Local<v8::FunctionTemplate> function_template = v8::Local<v8::FunctionTemplate> function_template =
per_isolate_data->FindInterfaceTemplate(world, callback_key); per_isolate_data->FindV8Template(world, callback_key)
.As<v8::FunctionTemplate>();
if (function_template.IsEmpty()) { if (function_template.IsEmpty()) {
function_template = v8::FunctionTemplate::New( function_template = v8::FunctionTemplate::New(
isolate, callback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), isolate, callback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(),
...@@ -285,8 +283,7 @@ v8::MaybeLocal<v8::Value> CreateNamedConstructorFunction( ...@@ -285,8 +283,7 @@ v8::MaybeLocal<v8::Value> CreateNamedConstructorFunction(
function_template->SetClassName(V8AtomicString(isolate, func_name)); function_template->SetClassName(V8AtomicString(isolate, func_name));
function_template->InstanceTemplate()->SetInternalFieldCount( function_template->InstanceTemplate()->SetInternalFieldCount(
kV8DefaultWrapperInternalFieldCount); kV8DefaultWrapperInternalFieldCount);
per_isolate_data->SetInterfaceTemplate(world, callback_key, per_isolate_data->AddV8Template(world, callback_key, function_template);
function_template);
} }
v8::Local<v8::Context> context = script_state->GetContext(); v8::Local<v8::Context> context = script_state->GetContext();
......
...@@ -906,7 +906,7 @@ v8::Local<v8::FunctionTemplate> V8DOMConfiguration::DomClassTemplate( ...@@ -906,7 +906,7 @@ v8::Local<v8::FunctionTemplate> V8DOMConfiguration::DomClassTemplate(
InstallTemplateFunction configure_dom_class_template) { InstallTemplateFunction configure_dom_class_template) {
V8PerIsolateData* data = V8PerIsolateData::From(isolate); V8PerIsolateData* data = V8PerIsolateData::From(isolate);
v8::Local<v8::FunctionTemplate> interface_template = v8::Local<v8::FunctionTemplate> interface_template =
data->FindInterfaceTemplate(world, wrapper_type_info); data->FindV8Template(world, wrapper_type_info).As<v8::FunctionTemplate>();
if (!interface_template.IsEmpty()) if (!interface_template.IsEmpty())
return interface_template; return interface_template;
...@@ -914,7 +914,7 @@ v8::Local<v8::FunctionTemplate> V8DOMConfiguration::DomClassTemplate( ...@@ -914,7 +914,7 @@ v8::Local<v8::FunctionTemplate> V8DOMConfiguration::DomClassTemplate(
interface_template = v8::FunctionTemplate::New( interface_template = v8::FunctionTemplate::New(
isolate, V8ObjectConstructor::IsValidConstructorMode); isolate, V8ObjectConstructor::IsValidConstructorMode);
configure_dom_class_template(isolate, world, interface_template); configure_dom_class_template(isolate, world, interface_template);
data->SetInterfaceTemplate(world, wrapper_type_info, interface_template); data->AddV8Template(world, wrapper_type_info, interface_template);
return interface_template; return interface_template;
} }
......
...@@ -413,8 +413,8 @@ void V8ContextSnapshotImpl::InstallInterfaceTemplates(v8::Isolate* isolate) { ...@@ -413,8 +413,8 @@ void V8ContextSnapshotImpl::InstallInterfaceTemplates(v8::Isolate* isolate) {
->GetDataFromSnapshotOnce<v8::FunctionTemplate>( ->GetDataFromSnapshotOnce<v8::FunctionTemplate>(
world_index * base::size(type_info_table) + i) world_index * base::size(type_info_table) + i)
.ToLocalChecked(); .ToLocalChecked();
per_isolate_data->SetInterfaceTemplate( per_isolate_data->AddV8Template(*world, type_info.wrapper_type_info,
*world, type_info.wrapper_type_info, interface_template); interface_template);
type_info.install_props_per_isolate( type_info.install_props_per_isolate(
isolate, *world, interface_template->InstanceTemplate(), isolate, *world, interface_template->InstanceTemplate(),
interface_template->PrototypeTemplate(), interface_template); interface_template->PrototypeTemplate(), interface_template);
......
...@@ -22,22 +22,20 @@ v8::MaybeLocal<v8::Function> GetCrossOriginFunction( ...@@ -22,22 +22,20 @@ v8::MaybeLocal<v8::Function> GetCrossOriginFunction(
V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate); V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate);
const void* callback_key = reinterpret_cast<const void*>(callback); const void* callback_key = reinterpret_cast<const void*>(callback);
// ES functions accessible across origins are not interface objects, but we
// reuse the cache of interface objects, which just works because both are
// V8 function template.
v8::Local<v8::FunctionTemplate> function_template = v8::Local<v8::FunctionTemplate> function_template =
per_isolate_data->FindInterfaceTemplate(script_state->World(), per_isolate_data->FindV8Template(script_state->World(), callback_key)
callback_key); .As<v8::FunctionTemplate>();
if (function_template.IsEmpty()) { if (function_template.IsEmpty()) {
v8::Local<v8::FunctionTemplate> interface_template = v8::Local<v8::FunctionTemplate> interface_template =
per_isolate_data->FindInterfaceTemplate(script_state->World(), per_isolate_data
wrapper_type_info); ->FindV8Template(script_state->World(), wrapper_type_info)
.As<v8::FunctionTemplate>();
v8::Local<v8::Signature> signature = v8::Local<v8::Signature> signature =
v8::Signature::New(isolate, interface_template); v8::Signature::New(isolate, interface_template);
function_template = v8::FunctionTemplate::New( function_template = v8::FunctionTemplate::New(
isolate, callback, v8::Local<v8::Value>(), signature, func_length, isolate, callback, v8::Local<v8::Value>(), signature, func_length,
v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasSideEffect); v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasSideEffect);
per_isolate_data->SetInterfaceTemplate(script_state->World(), callback_key, per_isolate_data->AddV8Template(script_state->World(), callback_key,
function_template); function_template);
} }
return function_template->GetFunction(current_context); return function_template->GetFunction(current_context);
......
...@@ -86,7 +86,8 @@ bool V8DOMWrapper::IsWrapper(v8::Isolate* isolate, v8::Local<v8::Value> value) { ...@@ -86,7 +86,8 @@ bool V8DOMWrapper::IsWrapper(v8::Isolate* isolate, v8::Local<v8::Value> value) {
V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate); V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate);
if (!(untrusted_wrapper_type_info && per_isolate_data)) if (!(untrusted_wrapper_type_info && per_isolate_data))
return false; return false;
return per_isolate_data->HasInstance(untrusted_wrapper_type_info, object); return per_isolate_data->HasInstanceOfUntrustedType(
untrusted_wrapper_type_info, object);
} }
bool V8DOMWrapper::HasInternalFieldsSet(v8::Local<v8::Value> value) { bool V8DOMWrapper::HasInternalFieldsSet(v8::Local<v8::Value> value) {
......
...@@ -90,8 +90,11 @@ V8PerIsolateData::V8PerIsolateData( ...@@ -90,8 +90,11 @@ V8PerIsolateData::V8PerIsolateData(
// This constructor is used for creating a V8 context snapshot. It must run on // This constructor is used for creating a V8 context snapshot. It must run on
// the main thread. // the main thread.
V8PerIsolateData::V8PerIsolateData() // TODO(yukishiino): This constructor may not be necessary. Probably We can
: v8_context_snapshot_mode_(V8ContextSnapshotMode::kTakeSnapshot), // reuse V8PerIsolateData(task_runner, v8_context_snapshot_mode) constructor.
V8PerIsolateData::V8PerIsolateData(
V8ContextSnapshotMode v8_context_snapshot_mode)
: v8_context_snapshot_mode_(v8_context_snapshot_mode),
isolate_holder_(Thread::Current()->GetTaskRunner(), isolate_holder_(Thread::Current()->GetTaskRunner(),
gin::IsolateHolder::kSingleThread, gin::IsolateHolder::kSingleThread,
gin::IsolateHolder::kAllowAtomicsWait, gin::IsolateHolder::kAllowAtomicsWait,
...@@ -104,6 +107,7 @@ V8PerIsolateData::V8PerIsolateData() ...@@ -104,6 +107,7 @@ V8PerIsolateData::V8PerIsolateData()
is_handling_recursion_level_error_(false), is_handling_recursion_level_error_(false),
runtime_call_stats_(base::DefaultTickClock::GetInstance()) { runtime_call_stats_(base::DefaultTickClock::GetInstance()) {
CHECK(IsMainThread()); CHECK(IsMainThread());
CHECK_EQ(v8_context_snapshot_mode_, V8ContextSnapshotMode::kTakeSnapshot);
// SnapshotCreator enters the isolate, so we don't call Isolate::Enter() here. // SnapshotCreator enters the isolate, so we don't call Isolate::Enter() here.
g_main_thread_per_isolate_data = this; g_main_thread_per_isolate_data = this;
...@@ -121,7 +125,7 @@ v8::Isolate* V8PerIsolateData::Initialize( ...@@ -121,7 +125,7 @@ v8::Isolate* V8PerIsolateData::Initialize(
V8ContextSnapshotMode context_mode) { V8ContextSnapshotMode context_mode) {
V8PerIsolateData* data = nullptr; V8PerIsolateData* data = nullptr;
if (context_mode == V8ContextSnapshotMode::kTakeSnapshot) { if (context_mode == V8ContextSnapshotMode::kTakeSnapshot) {
data = new V8PerIsolateData(); data = new V8PerIsolateData(context_mode);
} else { } else {
data = new V8PerIsolateData(task_runner, context_mode); data = new V8PerIsolateData(task_runner, context_mode);
} }
...@@ -190,10 +194,8 @@ void V8PerIsolateData::Destroy(v8::Isolate* isolate) { ...@@ -190,10 +194,8 @@ void V8PerIsolateData::Destroy(v8::Isolate* isolate) {
data->private_property_.reset(); data->private_property_.reset();
data->string_cache_->Dispose(); data->string_cache_->Dispose();
data->string_cache_.reset(); data->string_cache_.reset();
data->interface_template_map_for_non_main_world_.clear(); data->v8_template_map_for_main_world_.clear();
data->interface_template_map_for_main_world_.clear(); data->v8_template_map_for_non_main_worlds_.clear();
data->operation_template_map_for_non_main_world_.clear();
data->operation_template_map_for_main_world_.clear();
if (IsMainThread()) if (IsMainThread())
g_main_thread_per_isolate_data = nullptr; g_main_thread_per_isolate_data = nullptr;
...@@ -202,60 +204,80 @@ void V8PerIsolateData::Destroy(v8::Isolate* isolate) { ...@@ -202,60 +204,80 @@ void V8PerIsolateData::Destroy(v8::Isolate* isolate) {
delete data; delete data;
} }
V8PerIsolateData::V8FunctionTemplateMap& v8::Local<v8::Template> V8PerIsolateData::FindV8Template(
V8PerIsolateData::SelectInterfaceTemplateMap(const DOMWrapperWorld& world) {
return world.IsMainWorld() ? interface_template_map_for_main_world_
: interface_template_map_for_non_main_world_;
}
V8PerIsolateData::V8FunctionTemplateMap&
V8PerIsolateData::SelectOperationTemplateMap(const DOMWrapperWorld& world) {
return world.IsMainWorld() ? operation_template_map_for_main_world_
: operation_template_map_for_non_main_world_;
}
v8::Local<v8::FunctionTemplate> V8PerIsolateData::FindOrCreateOperationTemplate(
const DOMWrapperWorld& world, const DOMWrapperWorld& world,
const void* key, const void* key) {
v8::FunctionCallback callback, auto& map = SelectV8TemplateMap(world);
v8::Local<v8::Value> data,
v8::Local<v8::Signature> signature,
int length) {
auto& map = SelectOperationTemplateMap(world);
auto result = map.find(key); auto result = map.find(key);
if (result != map.end()) if (result != map.end())
return result->value.Get(GetIsolate()); return result->value.Get(GetIsolate());
return v8::Local<v8::Template>();
}
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New( void V8PerIsolateData::AddV8Template(const DOMWrapperWorld& world,
GetIsolate(), callback, data, signature, length); const void* key,
templ->RemovePrototype(); v8::Local<v8::Template> value) {
map.insert(key, v8::Eternal<v8::FunctionTemplate>(GetIsolate(), templ)); auto& map = SelectV8TemplateMap(world);
return templ; auto result = map.insert(key, v8::Eternal<v8::Template>(GetIsolate(), value));
DCHECK(result.is_new_entry);
} }
v8::Local<v8::FunctionTemplate> V8PerIsolateData::FindInterfaceTemplate( bool V8PerIsolateData::HasInstance(const WrapperTypeInfo* wrapper_type_info,
const DOMWrapperWorld& world, v8::Local<v8::Value> untrusted_value) {
const void* key) { RUNTIME_CALL_TIMER_SCOPE(GetIsolate(),
auto& map = SelectInterfaceTemplateMap(world); RuntimeCallStats::CounterId::kHasInstance);
auto result = map.find(key); return HasInstance(wrapper_type_info, untrusted_value,
if (result != map.end()) v8_template_map_for_main_world_) ||
return result->value.Get(GetIsolate()); HasInstance(wrapper_type_info, untrusted_value,
return v8::Local<v8::FunctionTemplate>(); v8_template_map_for_non_main_worlds_);
} }
void V8PerIsolateData::SetInterfaceTemplate( bool V8PerIsolateData::HasInstance(const WrapperTypeInfo* wrapper_type_info,
const DOMWrapperWorld& world, v8::Local<v8::Value> untrusted_value,
const void* key, const V8TemplateMap& map) {
v8::Local<v8::FunctionTemplate> value) { auto result = map.find(wrapper_type_info);
auto& map = SelectInterfaceTemplateMap(world); if (result == map.end())
map.insert(key, v8::Eternal<v8::FunctionTemplate>(GetIsolate(), value)); return false;
v8::Local<v8::Template> v8_template = result->value.Get(GetIsolate());
DCHECK(v8_template->IsFunctionTemplate());
return v8_template.As<v8::FunctionTemplate>()->HasInstance(untrusted_value);
}
bool V8PerIsolateData::HasInstanceOfUntrustedType(
const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value> untrusted_value) {
RUNTIME_CALL_TIMER_SCOPE(GetIsolate(),
RuntimeCallStats::CounterId::kHasInstance);
return HasInstanceOfUntrustedType(untrusted_wrapper_type_info,
untrusted_value,
v8_template_map_for_main_world_) ||
HasInstanceOfUntrustedType(untrusted_wrapper_type_info,
untrusted_value,
v8_template_map_for_non_main_worlds_);
}
bool V8PerIsolateData::HasInstanceOfUntrustedType(
const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value> untrusted_value,
const V8TemplateMap& map) {
auto result = map.find(untrusted_wrapper_type_info);
if (result == map.end())
return false;
v8::Local<v8::Template> v8_template = result->value.Get(GetIsolate());
if (!v8_template->IsFunctionTemplate())
return false;
return v8_template.As<v8::FunctionTemplate>()->HasInstance(untrusted_value);
}
V8PerIsolateData::V8TemplateMap& V8PerIsolateData::SelectV8TemplateMap(
const DOMWrapperWorld& world) {
return world.IsMainWorld() ? v8_template_map_for_main_world_
: v8_template_map_for_non_main_worlds_;
} }
void V8PerIsolateData::ClearPersistentsForV8ContextSnapshot() { void V8PerIsolateData::ClearPersistentsForV8ContextSnapshot() {
interface_template_map_for_main_world_.clear(); v8_template_map_for_main_world_.clear();
interface_template_map_for_non_main_world_.clear(); v8_template_map_for_non_main_worlds_.clear();
operation_template_map_for_main_world_.clear();
operation_template_map_for_non_main_world_.clear();
eternal_name_cache_.clear(); eternal_name_cache_.clear();
private_property_.reset(); private_property_.reset();
} }
...@@ -303,53 +325,6 @@ void V8PerIsolateData::ClearScriptRegexpContext() { ...@@ -303,53 +325,6 @@ void V8PerIsolateData::ClearScriptRegexpContext() {
script_regexp_script_state_ = nullptr; script_regexp_script_state_ = nullptr;
} }
bool V8PerIsolateData::HasInstance(
const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value> value) {
RUNTIME_CALL_TIMER_SCOPE(GetIsolate(),
RuntimeCallStats::CounterId::kHasInstance);
return HasInstance(untrusted_wrapper_type_info, value,
interface_template_map_for_main_world_) ||
HasInstance(untrusted_wrapper_type_info, value,
interface_template_map_for_non_main_world_);
}
bool V8PerIsolateData::HasInstance(
const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value> value,
V8FunctionTemplateMap& map) {
auto result = map.find(untrusted_wrapper_type_info);
if (result == map.end())
return false;
v8::Local<v8::FunctionTemplate> templ = result->value.Get(GetIsolate());
return templ->HasInstance(value);
}
v8::Local<v8::Object> V8PerIsolateData::FindInstanceInPrototypeChain(
const WrapperTypeInfo* info,
v8::Local<v8::Value> value) {
v8::Local<v8::Object> wrapper = FindInstanceInPrototypeChain(
info, value, interface_template_map_for_main_world_);
if (!wrapper.IsEmpty())
return wrapper;
return FindInstanceInPrototypeChain(
info, value, interface_template_map_for_non_main_world_);
}
v8::Local<v8::Object> V8PerIsolateData::FindInstanceInPrototypeChain(
const WrapperTypeInfo* info,
v8::Local<v8::Value> value,
V8FunctionTemplateMap& map) {
if (value.IsEmpty() || !value->IsObject())
return v8::Local<v8::Object>();
auto result = map.find(info);
if (result == map.end())
return v8::Local<v8::Object>();
v8::Local<v8::FunctionTemplate> templ = result->value.Get(GetIsolate());
return v8::Local<v8::Object>::Cast(value)->FindInstanceInPrototypeChain(
templ);
}
void V8PerIsolateData::AddEndOfScopeTask(base::OnceClosure task) { void V8PerIsolateData::AddEndOfScopeTask(base::OnceClosure task) {
end_of_scope_tasks_.push_back(std::move(task)); end_of_scope_tasks_.push_back(std::move(task));
} }
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
namespace base { namespace base {
class SingleThreadTaskRunner; class SingleThreadTaskRunner;
} } // namespace base
namespace blink { namespace blink {
...@@ -57,7 +57,7 @@ struct WrapperTypeInfo; ...@@ -57,7 +57,7 @@ struct WrapperTypeInfo;
// Used to hold data that is associated with a single v8::Isolate object, and // Used to hold data that is associated with a single v8::Isolate object, and
// has a 1:1 relationship with v8::Isolate. // has a 1:1 relationship with v8::Isolate.
class PLATFORM_EXPORT V8PerIsolateData { class PLATFORM_EXPORT V8PerIsolateData final {
USING_FAST_MALLOC(V8PerIsolateData); USING_FAST_MALLOC(V8PerIsolateData);
public: public:
...@@ -144,12 +144,18 @@ class PLATFORM_EXPORT V8PerIsolateData { ...@@ -144,12 +144,18 @@ class PLATFORM_EXPORT V8PerIsolateData {
V8PrivateProperty* PrivateProperty() { return private_property_.get(); } V8PrivateProperty* PrivateProperty() { return private_property_.get(); }
// Accessors to the cache of interface templates. // Accessors to the cache of v8::Templates.
v8::Local<v8::FunctionTemplate> FindInterfaceTemplate(const DOMWrapperWorld&, v8::Local<v8::Template> FindV8Template(const DOMWrapperWorld& world,
const void* key); const void* key);
void SetInterfaceTemplate(const DOMWrapperWorld&, void AddV8Template(const DOMWrapperWorld& world,
const void* key, const void* key,
v8::Local<v8::FunctionTemplate>); v8::Local<v8::Template> value);
bool HasInstance(const WrapperTypeInfo* wrapper_type_info,
v8::Local<v8::Value> untrusted_value);
bool HasInstanceOfUntrustedType(
const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value> untrusted_value);
// When v8::SnapshotCreator::CreateBlob() is called, we must not have // When v8::SnapshotCreator::CreateBlob() is called, we must not have
// persistent handles in Blink. This method clears them. // persistent handles in Blink. This method clears them.
...@@ -161,20 +167,6 @@ class PLATFORM_EXPORT V8PerIsolateData { ...@@ -161,20 +167,6 @@ class PLATFORM_EXPORT V8PerIsolateData {
V8ContextSnapshotMode GetV8ContextSnapshotMode() const { V8ContextSnapshotMode GetV8ContextSnapshotMode() const {
return v8_context_snapshot_mode_; return v8_context_snapshot_mode_;
} }
void BailoutAndDisableV8ContextSnapshot() {
DCHECK_EQ(V8ContextSnapshotMode::kUseSnapshot, v8_context_snapshot_mode_);
v8_context_snapshot_mode_ = V8ContextSnapshotMode::kDontUseSnapshot;
}
// Accessor to the cache of cross-origin accessible operation's templates.
// Created templates get automatically cached.
v8::Local<v8::FunctionTemplate> FindOrCreateOperationTemplate(
const DOMWrapperWorld&,
const void* key,
v8::FunctionCallback,
v8::Local<v8::Value> data,
v8::Local<v8::Signature>,
int length);
// Obtains a pointer to an array of names, given a lookup key. If it does not // Obtains a pointer to an array of names, given a lookup key. If it does not
// yet exist, it is created from the given array of strings. Once created, // yet exist, it is created from the given array of strings. Once created,
...@@ -184,10 +176,6 @@ class PLATFORM_EXPORT V8PerIsolateData { ...@@ -184,10 +176,6 @@ class PLATFORM_EXPORT V8PerIsolateData {
const void* lookup_key, const void* lookup_key,
const base::span<const char* const>& names); const base::span<const char* const>& names);
bool HasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>);
v8::Local<v8::Object> FindInstanceInPrototypeChain(const WrapperTypeInfo*,
v8::Local<v8::Value>);
v8::Local<v8::Context> EnsureScriptRegexpContext(); v8::Local<v8::Context> EnsureScriptRegexpContext();
void ClearScriptRegexpContext(); void ClearScriptRegexpContext();
...@@ -222,43 +210,38 @@ class PLATFORM_EXPORT V8PerIsolateData { ...@@ -222,43 +210,38 @@ class PLATFORM_EXPORT V8PerIsolateData {
private: private:
V8PerIsolateData(scoped_refptr<base::SingleThreadTaskRunner>, V8PerIsolateData(scoped_refptr<base::SingleThreadTaskRunner>,
V8ContextSnapshotMode); V8ContextSnapshotMode);
V8PerIsolateData(); explicit V8PerIsolateData(V8ContextSnapshotMode);
~V8PerIsolateData(); ~V8PerIsolateData();
// A really simple hash function, which makes lookups faster. The set of // A really simple hash function, which makes lookups faster. The set of
// possible keys for this is relatively small and fixed at compile time, so // possible keys for this is relatively small and fixed at compile time, so
// collisions are less of a worry than they would otherwise be. // collisions are less of a worry than they would otherwise be.
struct SimplePtrHash : WTF::PtrHash<const void> { struct SimplePtrHash final : public WTF::PtrHash<const void> {
static unsigned GetHash(const void* key) { static unsigned GetHash(const void* key) {
uintptr_t k = reinterpret_cast<uintptr_t>(key); uintptr_t k = reinterpret_cast<uintptr_t>(key);
return static_cast<unsigned>(k ^ (k >> 8)); return static_cast<unsigned>(k ^ (k >> 8));
} }
}; };
using V8FunctionTemplateMap = using V8TemplateMap =
HashMap<const void*, v8::Eternal<v8::FunctionTemplate>, SimplePtrHash>; HashMap<const void*, v8::Eternal<v8::Template>, SimplePtrHash>;
V8FunctionTemplateMap& SelectInterfaceTemplateMap(const DOMWrapperWorld&); V8TemplateMap& SelectV8TemplateMap(const DOMWrapperWorld&);
V8FunctionTemplateMap& SelectOperationTemplateMap(const DOMWrapperWorld&); bool HasInstance(const WrapperTypeInfo* wrapper_type_info,
bool HasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value> untrusted_value,
v8::Local<v8::Value>, const V8TemplateMap& map);
V8FunctionTemplateMap&); bool HasInstanceOfUntrustedType(
v8::Local<v8::Object> FindInstanceInPrototypeChain(const WrapperTypeInfo*, const WrapperTypeInfo* untrusted_wrapper_type_info,
v8::Local<v8::Value>, v8::Local<v8::Value> untrusted_value,
V8FunctionTemplateMap&); const V8TemplateMap& map);
V8ContextSnapshotMode v8_context_snapshot_mode_; V8ContextSnapshotMode v8_context_snapshot_mode_;
// This isolate_holder_ must be initialized before initializing some other // This isolate_holder_ must be initialized before initializing some other
// members below. // members below.
gin::IsolateHolder isolate_holder_; gin::IsolateHolder isolate_holder_;
// interface_template_map_for_{,non_}main_world holds function templates for // v8::Template cache of interface objects, namespace objects, etc.
// the inerface objects. V8TemplateMap v8_template_map_for_main_world_;
V8FunctionTemplateMap interface_template_map_for_main_world_; V8TemplateMap v8_template_map_for_non_main_worlds_;
V8FunctionTemplateMap interface_template_map_for_non_main_world_;
// m_operationTemplateMapFor{,Non}MainWorld holds function templates for
// the cross-origin accessible DOM operations.
V8FunctionTemplateMap operation_template_map_for_main_world_;
V8FunctionTemplateMap operation_template_map_for_non_main_world_;
// Contains lists of eternal names, such as dictionary keys. // Contains lists of eternal names, such as dictionary keys.
HashMap<const void*, Vector<v8::Eternal<v8::Name>>> eternal_name_cache_; HashMap<const void*, Vector<v8::Eternal<v8::Name>>> eternal_name_cache_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment