| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 63ebad5 commit ede9d2e
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,39 @@ | |||
| 15 | 15 | ||
| 16 | 16 | namespace v8_inspector { | |
| 17 | 17 | ||
| 18 | + class InspectedContext::WeakCallbackData { | ||
| 19 | + public: | ||
| 20 | + WeakCallbackData(InspectedContext* context, V8InspectorImpl* inspector, | ||
| 21 | + int groupId, int contextId) | ||
| 22 | + : m_context(context), | ||
| 23 | + m_inspector(inspector), | ||
| 24 | + m_groupId(groupId), | ||
| 25 | + m_contextId(contextId) {} | ||
| 26 | + | ||
| 27 | + static void resetContext(const v8::WeakCallbackInfo<WeakCallbackData>& data) { | ||
| 28 | + // InspectedContext is alive here because weak handler is still alive. | ||
| 29 | + data.GetParameter()->m_context->m_weakCallbackData = nullptr; | ||
| 30 | + data.GetParameter()->m_context->m_context.Reset(); | ||
| 31 | + data.SetSecondPassCallback(&callContextCollected); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + static void callContextCollected( | ||
| 35 | + const v8::WeakCallbackInfo<WeakCallbackData>& data) { | ||
| 36 | + // InspectedContext can be dead here since anything can happen between first | ||
| 37 | + // and second pass callback. | ||
| 38 | + WeakCallbackData* callbackData = data.GetParameter(); | ||
| 39 | + callbackData->m_inspector->contextCollected(callbackData->m_groupId, | ||
| 40 | + callbackData->m_contextId); | ||
| 41 | + delete callbackData; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + private: | ||
| 45 | + InspectedContext* m_context; | ||
| 46 | + V8InspectorImpl* m_inspector; | ||
| 47 | + int m_groupId; | ||
| 48 | + int m_contextId; | ||
| 49 | + }; | ||
| 50 | + | ||
| 18 | 51 | InspectedContext::InspectedContext(V8InspectorImpl* inspector, | |
| 19 | 52 | const V8ContextInfo& info, int contextId) | |
| 20 | 53 | : m_inspector(inspector), | |
@@ -25,6 +58,11 @@ InspectedContext::InspectedContext(V8InspectorImpl* inspector, | |||
| 25 | 58 | m_humanReadableName(toString16(info.humanReadableName)), | |
| 26 | 59 | m_auxData(toString16(info.auxData)) { | |
| 27 | 60 | v8::debug::SetContextId(info.context, contextId); | |
| 61 | + m_weakCallbackData = | ||
| 62 | + new WeakCallbackData(this, m_inspector, m_contextGroupId, m_contextId); | ||
| 63 | + m_context.SetWeak(m_weakCallbackData, | ||
| 64 | + &InspectedContext::WeakCallbackData::resetContext, | ||
| 65 | + v8::WeakCallbackType::kParameter); | ||
| 28 | 66 | if (!info.hasMemoryOnConsole) return; | |
| 29 | 67 | v8::Context::Scope contextScope(info.context); | |
| 30 | 68 | v8::Local<v8::Object> global = info.context->Global(); | |
@@ -38,6 +76,9 @@ InspectedContext::InspectedContext(V8InspectorImpl* inspector, | |||
| 38 | 76 | } | |
| 39 | 77 | ||
| 40 | 78 | InspectedContext::~InspectedContext() { | |
| 79 | + // If we destory InspectedContext before weak callback is invoked then we need | ||
| 80 | + // to delete data here. | ||
| 81 | + if (!m_context.IsEmpty()) delete m_weakCallbackData; | ||
| 41 | 82 | } | |
| 42 | 83 | ||
| 43 | 84 | // static | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,6 +47,8 @@ class InspectedContext { | |||
| 47 | 47 | friend class V8InspectorImpl; | |
| 48 | 48 | InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId); | |
| 49 | 49 | ||
| 50 | + class WeakCallbackData; | ||
| 51 | + | ||
| 50 | 52 | V8InspectorImpl* m_inspector; | |
| 51 | 53 | v8::Global<v8::Context> m_context; | |
| 52 | 54 | int m_contextId; | |
@@ -56,6 +58,7 @@ class InspectedContext { | |||
| 56 | 58 | const String16 m_auxData; | |
| 57 | 59 | std::unordered_set<int> m_reportedSessionIds; | |
| 58 | 60 | std::unordered_map<int, std::unique_ptr<InjectedScript>> m_injectedScripts; | |
| 61 | + WeakCallbackData* m_weakCallbackData; | ||
| 59 | 62 | ||
| 60 | 63 | DISALLOW_COPY_AND_ASSIGN(InspectedContext); | |
| 61 | 64 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -203,6 +203,10 @@ void V8InspectorImpl::contextCreated(const V8ContextInfo& info) { | |||
| 203 | 203 | void V8InspectorImpl::contextDestroyed(v8::Local<v8::Context> context) { | |
| 204 | 204 | int contextId = InspectedContext::contextId(context); | |
| 205 | 205 | int groupId = contextGroupId(context); | |
| 206 | + contextCollected(groupId, contextId); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + void V8InspectorImpl::contextCollected(int groupId, int contextId) { | ||
| 206 | 210 | m_contextIdToGroupIdMap.erase(contextId); | |
| 207 | 211 | ||
| 208 | 212 | ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(groupId); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,6 +74,7 @@ class V8InspectorImpl : public V8Inspector { | |||
| 74 | 74 | const StringView& state) override; | |
| 75 | 75 | void contextCreated(const V8ContextInfo&) override; | |
| 76 | 76 | void contextDestroyed(v8::Local<v8::Context>) override; | |
| 77 | + void contextCollected(int contextGroupId, int contextId); | ||
| 77 | 78 | void resetContextGroup(int contextGroupId) override; | |
| 78 | 79 | void idleStarted() override; | |
| 79 | 80 | void idleFinished() override; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -642,6 +642,9 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { | |||
| 642 | 642 | inspector->Set(ToV8String(isolate, "fireContextDestroyed"), | |
| 643 | 643 | v8::FunctionTemplate::New( | |
| 644 | 644 | isolate, &InspectorExtension::FireContextDestroyed)); | |
| 645 | + inspector->Set( | ||
| 646 | + ToV8String(isolate, "freeContext"), | ||
| 647 | + v8::FunctionTemplate::New(isolate, &InspectorExtension::FreeContext)); | ||
| 645 | 648 | inspector->Set(ToV8String(isolate, "addInspectedObject"), | |
| 646 | 649 | v8::FunctionTemplate::New( | |
| 647 | 650 | isolate, &InspectorExtension::AddInspectedObject)); | |
@@ -683,6 +686,12 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { | |||
| 683 | 686 | data->FireContextDestroyed(context); | |
| 684 | 687 | } | |
| 685 | 688 | ||
| 689 | + static void FreeContext(const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| 690 | + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); | ||
| 691 | + IsolateData* data = IsolateData::FromContext(context); | ||
| 692 | + data->FreeContext(context); | ||
| 693 | + } | ||
| 694 | + | ||
| 686 | 695 | static void AddInspectedObject( | |
| 687 | 696 | const v8::FunctionCallbackInfo<v8::Value>& args) { | |
| 688 | 697 | if (args.Length() != 2 || !args[0]->IsInt32()) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -303,6 +303,13 @@ void IsolateData::FireContextDestroyed(v8::Local<v8::Context> context) { | |||
| 303 | 303 | inspector_->contextDestroyed(context); | |
| 304 | 304 | } | |
| 305 | 305 | ||
| 306 | + void IsolateData::FreeContext(v8::Local<v8::Context> context) { | ||
| 307 | + int context_group_id = GetContextGroupId(context); | ||
| 308 | + auto it = contexts_.find(context_group_id); | ||
| 309 | + if (it == contexts_.end()) return; | ||
| 310 | + contexts_.erase(it); | ||
| 311 | + } | ||
| 312 | + | ||
| 306 | 313 | std::vector<int> IsolateData::GetSessionIds(int context_group_id) { | |
| 307 | 314 | std::vector<int> result; | |
| 308 | 315 | for (auto& it : sessions_) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,6 +68,7 @@ class IsolateData : public v8_inspector::V8InspectorClient { | |||
| 68 | 68 | void DumpAsyncTaskStacksStateForTest(); | |
| 69 | 69 | void FireContextCreated(v8::Local<v8::Context> context, int context_group_id); | |
| 70 | 70 | void FireContextDestroyed(v8::Local<v8::Context> context); | |
| 71 | + void FreeContext(v8::Local<v8::Context> context); | ||
| 71 | 72 | ||
| 72 | 73 | private: | |
| 73 | 74 | struct VectorCompare { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,7 @@ | |||
| 1 | + Tests that contextDesrtoyed nofitication is fired when context is collected. | ||
| 2 | + { | ||
| 3 | + method : Runtime.executionContextDestroyed | ||
| 4 | + params : { | ||
| 5 | + executionContextId : <executionContextId> | ||
| 6 | + } | ||
| 7 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,14 @@ | |||
| 1 | + // Copyright 2017 the V8 project authors. All rights reserved. | ||
| 2 | + // Use of this source code is governed by a BSD-style license that can be | ||
| 3 | + // found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + let {session, contextGroup, Protocol} = | ||
| 6 | + InspectorTest.start('Tests that contextDesrtoyed nofitication is fired when context is collected.'); | ||
| 7 | + | ||
| 8 | + (async function test() { | ||
| 9 | + await Protocol.Runtime.enable(); | ||
| 10 | + Protocol.Runtime.onExecutionContextDestroyed(InspectorTest.logMessage); | ||
| 11 | + contextGroup.addScript('inspector.freeContext()'); | ||
| 12 | + await Protocol.HeapProfiler.collectGarbage(); | ||
| 13 | + InspectorTest.completeTest(); | ||
| 14 | + })(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments