0

Plumb extension host_id through the content layer.

Add a generic "stable ID" to WebLocalFrame. The embedder can set this
when creating an isolated world with WebIsolatedWorldInfo and retrieve
it with an accessor on WebLocalFrame.  Extensions set this to host_id.

Also exposes the human readable name which already exists in
WebLocalFrame through an accessor.

V8PerFrameMemoryDecorator will retrieve the stable ID and human readable
name to annotate the memory usage of non-main isolated worlds.

R=siggi,jochen

Bug: 1080672
Change-Id: I01bdc6a2d6fd404053a0990cad9e9855189e9584
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2231668
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Will Harris <wfh@chromium.org>
Reviewed-by: Sigurður Ásgeirsson <siggi@chromium.org>
Commit-Queue: Will Harris <wfh@chromium.org>
Auto-Submit: Joe Mason <joenotcharles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#777509}
This commit is contained in:
Joe Mason
2020-06-11 21:55:12 +00:00
committed by Commit Bot
parent 9f5bdac81c
commit c366d29562
9 changed files with 79 additions and 9 deletions
content
public
common
performance_manager
renderer
extensions/renderer
third_party/blink

@ -11,9 +11,18 @@ struct V8IsolatedWorldMemoryUsage {
// The number of v8 heap bytes used by a V8 isolated world.
uint64 bytes_used = 0;
// The isolated world host ID if any, as per
/// ScriptInjection::GetHostIdForIsolatedWorld.
string host_id;
// An optional tag for this world that does not vary between browser sessions
// or between renderers, unlike the world ID which can be randomly assigned.
//
// The exact meaning depends on the embedder and the type of isolated world.
// For example Chrome extensions use the host ID, as per
// extensions::ScriptInjection::GetHostIdForIsolatedWorld. Some types of
// isolated world will not have a suitable tag so will leave this empty.
string stable_id;
// An optional human readable name for the world, for debugging. Unlike
// stable_id this might not be unique.
string human_readable_name;
};
// Returns the number of bytes used by the v8 heap per frame.

@ -73,10 +73,12 @@ class FrameAssociatedMeasurementDelegate : public v8::MeasureMemoryDelegate {
isolated_world_usage->bytes_used = size;
int32_t world_id = frame->GetScriptContextWorldId(context);
// TODO(crbug.com/1080672): Populate isolated_world_usage->host_id.
// This will need a delegate to plumb through the value from
// extensions::ScriptInjection::GetHostIdForIsolatedWorld for embedders
// that support extensions.
if (world_id != content::ISOLATED_WORLD_ID_GLOBAL) {
isolated_world_usage->stable_id =
frame->GetIsolatedWorldStableId(context).Utf8();
isolated_world_usage->human_readable_name =
frame->GetIsolatedWorldHumanReadableName(context).Utf8();
}
DCHECK(
!base::Contains(per_frame_resources->associated_bytes, world_id));

@ -74,6 +74,7 @@ int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host,
info.security_origin =
blink::WebSecurityOrigin::Create(injection_host->url());
info.human_readable_name = blink::WebString::FromUTF8(injection_host->name());
info.stable_id = blink::WebString::FromUTF8(key);
const std::string* csp = injection_host->GetContentSecurityPolicy();
if (csp)

@ -38,6 +38,15 @@ struct WebIsolatedWorldInfo {
// Associates an isolated world with human-readable name which is useful for
// extension debugging.
WebString human_readable_name;
// Associates an isolated world with an optional tag that does not vary
// between browser sessions or between renderers, unlike the world ID which
// can be randomly assigned. The exact meaning will depend on the embedder
// and the type of isolated world. For example Chrome extensions use the
// host ID, as per extensions::ScriptInjection::GetHostIdForIsolatedWorld.
// Some types of isolated world will not have a suitable tag so will leave
// this empty.
WebString stable_id;
};
} // namespace blink

@ -322,6 +322,13 @@ class WebLocalFrame : public WebFrame {
virtual void SetIsolatedWorldInfo(int32_t world_id,
const WebIsolatedWorldInfo& info) = 0;
// Returns the stable ID that was set with SetIsolatedWorldInfo.
virtual WebString GetIsolatedWorldStableId(v8::Local<v8::Context>) const = 0;
// Returns the human readable name that was set with SetIsolatedWorldInfo.
virtual WebString GetIsolatedWorldHumanReadableName(
v8::Local<v8::Context>) const = 0;
// Executes script in the context of the current page and returns the value
// that the script evaluated to.
// DEPRECATED: Use WebLocalFrame::requestExecuteScriptAndReturnValue.

@ -824,12 +824,27 @@ void WebLocalFrameImpl::SetIsolatedWorldInfo(int32_t world_id,
CHECK(info.content_security_policy.IsNull() || security_origin);
DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(world_id, security_origin);
DOMWrapperWorld::SetNonMainWorldStableId(world_id, info.stable_id);
DOMWrapperWorld::SetNonMainWorldHumanReadableName(world_id,
info.human_readable_name);
IsolatedWorldCSP::Get().SetContentSecurityPolicy(
world_id, info.content_security_policy, security_origin);
}
WebString WebLocalFrameImpl::GetIsolatedWorldStableId(
v8::Local<v8::Context> context) const {
const DOMWrapperWorld& world = DOMWrapperWorld::World(context);
DCHECK(!world.IsMainWorld());
return world.NonMainWorldStableId();
}
WebString WebLocalFrameImpl::GetIsolatedWorldHumanReadableName(
v8::Local<v8::Context> context) const {
const DOMWrapperWorld& world = DOMWrapperWorld::World(context);
DCHECK(!world.IsMainWorld());
return world.NonMainWorldHumanReadableName();
}
void WebLocalFrameImpl::Alert(const WebString& message) {
DCHECK(GetFrame());
ScriptState* script_state = ToScriptStateForMainWorld(GetFrame());

@ -152,6 +152,10 @@ class CORE_EXPORT WebLocalFrameImpl final
void ClearIsolatedWorldCSPForTesting(int32_t world_id) override;
void SetIsolatedWorldInfo(int32_t world_id,
const WebIsolatedWorldInfo&) override;
WebString GetIsolatedWorldStableId(
v8::Local<v8::Context> context) const override;
WebString GetIsolatedWorldHumanReadableName(
v8::Local<v8::Context> context) const override;
v8::Local<v8::Value> ExecuteScriptAndReturnValue(
const WebScriptSource&) override;
v8::MaybeLocal<v8::Value> CallFunctionEvenIfScriptDisabled(

@ -175,6 +175,26 @@ void DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(
IsolatedWorldSecurityOrigins().erase(world_id);
}
typedef HashMap<int, String> IsolatedWorldStableIdMap;
static IsolatedWorldStableIdMap& IsolatedWorldStableIds() {
DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(IsolatedWorldStableIdMap, map, ());
return map;
}
String DOMWrapperWorld::NonMainWorldStableId() const {
DCHECK(!this->IsMainWorld());
return IsolatedWorldStableIds().at(GetWorldId());
}
void DOMWrapperWorld::SetNonMainWorldStableId(int32_t world_id,
const String& stable_id) {
#if DCHECK_IS_ON()
DCHECK(!IsMainWorldId(world_id));
#endif
IsolatedWorldStableIds().Set(world_id, stable_id);
}
typedef HashMap<int, String> IsolatedWorldHumanReadableNameMap;
static IsolatedWorldHumanReadableNameMap& IsolatedWorldHumanReadableNames() {
DCHECK(IsMainThread());
@ -182,7 +202,7 @@ static IsolatedWorldHumanReadableNameMap& IsolatedWorldHumanReadableNames() {
return map;
}
String DOMWrapperWorld::NonMainWorldHumanReadableName() {
String DOMWrapperWorld::NonMainWorldHumanReadableName() const {
DCHECK(!this->IsMainWorld());
return IsolatedWorldHumanReadableNames().at(GetWorldId());
}

@ -115,8 +115,11 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
static DOMWrapperWorld& MainWorld();
static void SetNonMainWorldStableId(int32_t world_id, const String&);
String NonMainWorldStableId() const;
static void SetNonMainWorldHumanReadableName(int32_t world_id, const String&);
String NonMainWorldHumanReadableName();
String NonMainWorldHumanReadableName() const;
// Associates an isolated world (see above for description) with a security
// origin. XMLHttpRequest instances used in that world will be considered