[inspector] Move m_internalObjects into InspectedContext.

That should prevent leak of objects when page is reloaded.

BUG=chromium:906847

Change-Id: I90928a5c4979c0ddc01c201bf60a693e2b03863a
Reviewed-on: https://chromium-review.googlesource.com/c/1366449
Commit-Queue: Alexei Filippov <alph@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58110}
This commit is contained in:
Alexei Filippov 2018-12-07 15:20:28 -08:00 committed by Commit Bot
parent 6275e7e2ee
commit c198a9b497
5 changed files with 50 additions and 40 deletions

View File

@ -121,4 +121,28 @@ void InspectedContext::discardInjectedScript(int sessionId) {
m_injectedScripts.erase(sessionId); m_injectedScripts.erase(sessionId);
} }
bool InspectedContext::addInternalObject(v8::Local<v8::Object> object,
V8InternalValueType type) {
if (m_internalObjects.IsEmpty()) {
m_internalObjects.Reset(isolate(), v8::debug::WeakMap::New(isolate()));
}
return !m_internalObjects.Get(isolate())
->Set(m_context.Get(isolate()), object,
v8::Integer::New(isolate(), static_cast<int>(type)))
.IsEmpty();
}
V8InternalValueType InspectedContext::getInternalType(
v8::Local<v8::Object> object) {
if (m_internalObjects.IsEmpty()) return V8InternalValueType::kNone;
v8::Local<v8::Value> typeValue;
if (!m_internalObjects.Get(isolate())
->Get(m_context.Get(isolate()), object)
.ToLocal(&typeValue) ||
!typeValue->IsUint32()) {
return V8InternalValueType::kNone;
}
return static_cast<V8InternalValueType>(typeValue.As<v8::Int32>()->Value());
}
} // namespace v8_inspector } // namespace v8_inspector

View File

@ -9,6 +9,7 @@
#include <unordered_set> #include <unordered_set>
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/debug/debug-interface.h"
#include "src/inspector/string-16.h" #include "src/inspector/string-16.h"
#include "include/v8.h" #include "include/v8.h"
@ -20,6 +21,8 @@ class InjectedScriptHost;
class V8ContextInfo; class V8ContextInfo;
class V8InspectorImpl; class V8InspectorImpl;
enum class V8InternalValueType { kNone, kEntry, kScope, kScopeList };
class InspectedContext { class InspectedContext {
public: public:
~InspectedContext(); ~InspectedContext();
@ -43,6 +46,10 @@ class InspectedContext {
InjectedScript* createInjectedScript(int sessionId); InjectedScript* createInjectedScript(int sessionId);
void discardInjectedScript(int sessionId); void discardInjectedScript(int sessionId);
bool addInternalObject(v8::Local<v8::Object> object,
V8InternalValueType type);
V8InternalValueType getInternalType(v8::Local<v8::Object> object);
private: private:
friend class V8InspectorImpl; friend class V8InspectorImpl;
InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId); InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId);
@ -59,6 +66,7 @@ class InspectedContext {
std::unordered_set<int> m_reportedSessionIds; std::unordered_set<int> m_reportedSessionIds;
std::unordered_map<int, std::unique_ptr<InjectedScript>> m_injectedScripts; std::unordered_map<int, std::unique_ptr<InjectedScript>> m_injectedScripts;
WeakCallbackData* m_weakCallbackData; WeakCallbackData* m_weakCallbackData;
v8::Global<v8::debug::WeakMap> m_internalObjects;
DISALLOW_COPY_AND_ASSIGN(InspectedContext); DISALLOW_COPY_AND_ASSIGN(InspectedContext);
}; };

View File

@ -603,9 +603,8 @@ v8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
for (; !iterator->Done(); iterator->Advance()) { for (; !iterator->Done(); iterator->Advance()) {
v8::Local<v8::Object> scope = v8::Object::New(m_isolate); v8::Local<v8::Object> scope = v8::Object::New(m_isolate);
if (!addInternalObject(context, scope, V8InternalValueType::kScope)) { if (!addInternalObject(context, scope, V8InternalValueType::kScope))
return v8::MaybeLocal<v8::Value>(); return v8::MaybeLocal<v8::Value>();
}
String16 nameSuffix = toProtocolStringWithTypeCheck( String16 nameSuffix = toProtocolStringWithTypeCheck(
m_isolate, iterator->GetFunctionDebugName()); m_isolate, iterator->GetFunctionDebugName());
String16 description; String16 description;
@ -647,8 +646,7 @@ v8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
toV8StringInternalized(m_isolate, "object"), object); toV8StringInternalized(m_isolate, "object"), object);
createDataProperty(context, result, result->Length(), scope); createDataProperty(context, result, result->Length(), scope);
} }
if (!addInternalObject(context, v8::Local<v8::Array>::Cast(result), if (!addInternalObject(context, result, V8InternalValueType::kScopeList))
V8InternalValueType::kScopeList))
return v8::MaybeLocal<v8::Value>(); return v8::MaybeLocal<v8::Value>();
return result; return result;
} }
@ -693,9 +691,8 @@ v8::MaybeLocal<v8::Array> V8Debugger::collectionsEntries(
createDataProperty(context, wrapper, createDataProperty(context, wrapper,
toV8StringInternalized(isolate, "value"), value); toV8StringInternalized(isolate, "value"), value);
} }
if (!addInternalObject(context, wrapper, V8InternalValueType::kEntry)) { if (!addInternalObject(context, wrapper, V8InternalValueType::kEntry))
continue; continue;
}
createDataProperty(context, wrappedEntries, wrappedEntries->Length(), createDataProperty(context, wrappedEntries, wrappedEntries->Length(),
wrapper); wrapper);
} }
@ -1091,26 +1088,10 @@ std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor(
bool V8Debugger::addInternalObject(v8::Local<v8::Context> context, bool V8Debugger::addInternalObject(v8::Local<v8::Context> context,
v8::Local<v8::Object> object, v8::Local<v8::Object> object,
V8InternalValueType type) { V8InternalValueType type) {
if (m_internalObjects.IsEmpty()) { int contextId = InspectedContext::contextId(context);
m_internalObjects.Reset(m_isolate, v8::debug::WeakMap::New(m_isolate)); InspectedContext* inspectedContext = m_inspector->getContext(contextId);
} return inspectedContext ? inspectedContext->addInternalObject(object, type)
return !m_internalObjects.Get(m_isolate) : false;
->Set(context, object,
v8::Integer::New(m_isolate, static_cast<int>(type)))
.IsEmpty();
}
V8InternalValueType V8Debugger::getInternalType(v8::Local<v8::Context> context,
v8::Local<v8::Object> object) {
if (m_internalObjects.IsEmpty()) return V8InternalValueType::kNone;
v8::Local<v8::Value> typeValue;
if (!m_internalObjects.Get(m_isolate)
->Get(context, object)
.ToLocal(&typeValue) ||
!typeValue->IsUint32()) {
return V8InternalValueType::kNone;
}
return static_cast<V8InternalValueType>(typeValue.As<v8::Int32>()->Value());
} }
void V8Debugger::dumpAsyncTaskStacksStateForTest() { void V8Debugger::dumpAsyncTaskStacksStateForTest() {

View File

@ -11,7 +11,7 @@
#include <vector> #include <vector>
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/debug/debug-interface.h" #include "src/inspector/inspected-context.h"
#include "src/inspector/protocol/Debugger.h" #include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/Forward.h"
#include "src/inspector/protocol/Runtime.h" #include "src/inspector/protocol/Runtime.h"
@ -31,7 +31,6 @@ class V8StackTraceImpl;
struct V8StackTraceId; struct V8StackTraceId;
enum class WrapMode { kForceValue, kNoPreview, kWithPreview }; enum class WrapMode { kForceValue, kNoPreview, kWithPreview };
enum class V8InternalValueType { kNone, kEntry, kScope, kScopeList };
using protocol::Response; using protocol::Response;
using TerminateExecutionCallback = using TerminateExecutionCallback =
@ -132,15 +131,13 @@ class V8Debugger : public v8::debug::DebugDelegate,
std::shared_ptr<AsyncStackTrace> stackTraceFor(int contextGroupId, std::shared_ptr<AsyncStackTrace> stackTraceFor(int contextGroupId,
const V8StackTraceId& id); const V8StackTraceId& id);
bool addInternalObject(v8::Local<v8::Context> context,
v8::Local<v8::Object> object,
V8InternalValueType type);
V8InternalValueType getInternalType(v8::Local<v8::Context> context,
v8::Local<v8::Object> object);
void reportTermination(); void reportTermination();
private: private:
bool addInternalObject(v8::Local<v8::Context> context,
v8::Local<v8::Object> object,
V8InternalValueType type);
void clearContinueToLocation(); void clearContinueToLocation();
bool shouldContinueToCurrentLocation(); bool shouldContinueToCurrentLocation();
@ -254,8 +251,6 @@ class V8Debugger : public v8::debug::DebugDelegate,
std::unique_ptr<TerminateExecutionCallback> m_terminateExecutionCallback; std::unique_ptr<TerminateExecutionCallback> m_terminateExecutionCallback;
v8::Global<v8::debug::WeakMap> m_internalObjects;
WasmTranslation m_wasmTranslation; WasmTranslation m_wasmTranslation;
DISALLOW_COPY_AND_ASSIGN(V8Debugger); DISALLOW_COPY_AND_ASSIGN(V8Debugger);

View File

@ -31,10 +31,12 @@ V8InspectorClient* clientFor(v8::Local<v8::Context> context) {
V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context, V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context,
v8::Local<v8::Value> value) { v8::Local<v8::Value> value) {
if (!value->IsObject()) return V8InternalValueType::kNone; if (!value->IsObject()) return V8InternalValueType::kNone;
V8Debugger* debugger = static_cast<V8InspectorImpl*>( V8InspectorImpl* inspector = static_cast<V8InspectorImpl*>(
v8::debug::GetInspector(context->GetIsolate())) v8::debug::GetInspector(context->GetIsolate()));
->debugger(); int contextId = InspectedContext::contextId(context);
return debugger->getInternalType(context, value.As<v8::Object>()); InspectedContext* inspectedContext = inspector->getContext(contextId);
if (!inspectedContext) return V8InternalValueType::kNone;
return inspectedContext->getInternalType(value.As<v8::Object>());
} }
Response toProtocolValue(v8::Local<v8::Context> context, Response toProtocolValue(v8::Local<v8::Context> context,