From 77419fc108b188375a1df62ef06a4357f809f82f Mon Sep 17 00:00:00 2001 From: wengchangcheng Date: Wed, 6 Apr 2022 20:07:34 +0800 Subject: [PATCH] refactor debugger part-3 1. get extractor from JSPandaFileManager 2. cache extractor map with url as key 3. get sourcecode from mainIndex, instead of traversal all methods issue: https://gitee.com/openharmony/ark_js_runtime/issues/I51E4Y Signed-off-by: wengchangcheng Change-Id: I8ae35d65318bb0969a2ce80c42993ae535462de4 --- .../jspandafile/debug_info_extractor.cpp | 4 +- ecmascript/jspandafile/js_pandafile.cpp | 1 + ecmascript/jspandafile/js_pandafile.h | 1 - ecmascript/tooling/agent/js_backend.cpp | 69 ++++++++----------- ecmascript/tooling/agent/js_backend.h | 2 +- 5 files changed, 31 insertions(+), 46 deletions(-) diff --git a/ecmascript/jspandafile/debug_info_extractor.cpp b/ecmascript/jspandafile/debug_info_extractor.cpp index 4f030c03df..be336ba50e 100644 --- a/ecmascript/jspandafile/debug_info_extractor.cpp +++ b/ecmascript/jspandafile/debug_info_extractor.cpp @@ -301,7 +301,7 @@ const CString &DebugInfoExtractor::GetSourceFile(panda_file::File::EntityId meth { auto iter = methods_.find(methodId.GetOffset()); if (iter == methods_.end()) { - return CString(""); + LOG(FATAL, DEBUGGER) << "Get source file of unknown method id: " << methodId.GetOffset(); } return iter->second.sourceFile; } @@ -310,7 +310,7 @@ const CString &DebugInfoExtractor::GetSourceCode(panda_file::File::EntityId meth { auto iter = methods_.find(methodId.GetOffset()); if (iter == methods_.end()) { - return CString(""); + LOG(FATAL, DEBUGGER) << "Get source code of unknown method id: " << methodId.GetOffset(); } return iter->second.sourceCode; } diff --git a/ecmascript/jspandafile/js_pandafile.cpp b/ecmascript/jspandafile/js_pandafile.cpp index ee78e7c019..6bf4e9611f 100644 --- a/ecmascript/jspandafile/js_pandafile.cpp +++ b/ecmascript/jspandafile/js_pandafile.cpp @@ -14,6 +14,7 @@ */ #include "ecmascript/jspandafile/js_pandafile.h" + #include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/jspandafile/program_object-inl.h" diff --git a/ecmascript/jspandafile/js_pandafile.h b/ecmascript/jspandafile/js_pandafile.h index a4d80d0b3a..6f9c7ab3fa 100644 --- a/ecmascript/jspandafile/js_pandafile.h +++ b/ecmascript/jspandafile/js_pandafile.h @@ -18,7 +18,6 @@ #include "ecmascript/js_method.h" #include "ecmascript/jspandafile/constpool_value.h" -#include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/mem/c_containers.h" #include "libpandafile/file.h" #include "libpandabase/utils/logger.h" diff --git a/ecmascript/tooling/agent/js_backend.cpp b/ecmascript/tooling/agent/js_backend.cpp index dff967617f..b49d4a12db 100644 --- a/ecmascript/tooling/agent/js_backend.cpp +++ b/ecmascript/tooling/agent/js_backend.cpp @@ -15,13 +15,14 @@ #include "ecmascript/tooling/agent/js_backend.h" -#include "ecmascript/jspandafile/js_pandafile.h" +#include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/tooling/base/pt_events.h" #include "ecmascript/tooling/front_end.h" #include "ecmascript/tooling/protocol_handler.h" #include "libpandafile/class_data_accessor-inl.h" namespace panda::tooling::ecmascript { +using panda::ecmascript::JSPandaFileManager; using ObjectType = RemoteObject::TypeName; using ObjectSubType = RemoteObject::SubTypeName; using ObjectClassName = RemoteObject::ClassName; @@ -112,6 +113,11 @@ void JSBackend::NotifyAllScriptParsed() bool JSBackend::NotifyScriptParsed(ScriptId scriptId, const CString &fileName) { + if (fileName.substr(0, DATA_APP_PATH.length()) != DATA_APP_PATH) { + LOG(WARNING, DEBUGGER) << "NotifyScriptParsed: unsupport file: " << fileName; + return false; + } + auto scriptFunc = []([[maybe_unused]] PtScript *script) -> bool { return true; }; @@ -120,7 +126,7 @@ bool JSBackend::NotifyScriptParsed(ScriptId scriptId, const CString &fileName) return false; } const JSPandaFile *jsPandaFile = nullptr; - ::panda::ecmascript::JSPandaFileManager::GetInstance()->EnumerateJSPandaFiles([&jsPandaFile, &fileName]( + JSPandaFileManager::GetInstance()->EnumerateJSPandaFiles([&jsPandaFile, &fileName]( const panda::ecmascript::JSPandaFile *pf) { if (pf->GetJSPandaFileDesc() == fileName) { jsPandaFile = pf; @@ -129,31 +135,27 @@ bool JSBackend::NotifyScriptParsed(ScriptId scriptId, const CString &fileName) return true; }); if (jsPandaFile == nullptr) { - LOG(WARNING, DEBUGGER) << "NotifyScriptParsed: unknown file: " << fileName; + LOG(ERROR, DEBUGGER) << "NotifyScriptParsed: unknown file: " << fileName; return false; } - JSPtExtractor *extractor = GenerateExtractor(jsPandaFile); + JSPtExtractor *extractor = GetExtractor(jsPandaFile); if (extractor == nullptr) { LOG(ERROR, DEBUGGER) << "NotifyScriptParsed: Unsupported file: " << fileName; return false; } - CString url; - CString source; + auto mainMethodIndex = panda_file::File::EntityId(jsPandaFile->GetMainMethodIndex()); + const CString &source = extractor->GetSourceCode(mainMethodIndex); + const CString &url = extractor->GetSourceFile(mainMethodIndex); const uint32_t MIN_SOURCE_CODE_LENGTH = 5; // maybe return 'ANDA' when source code is empty - for (const auto &method : extractor->GetMethodIdList()) { - source = extractor->GetSourceCode(method); - // only main function has source code - if (source.size() >= MIN_SOURCE_CODE_LENGTH) { - url = extractor->GetSourceFile(method); - break; - } - } - if (url.empty()) { + if (source.size() < MIN_SOURCE_CODE_LENGTH) { LOG(ERROR, DEBUGGER) << "NotifyScriptParsed: invalid file: " << fileName; return false; } + // store here for performance of get extractor from url + extractors_[url] = extractor; + // Notify script parsed event std::unique_ptr script = std::make_unique(scriptId, fileName, url, source); @@ -200,6 +202,10 @@ std::optional JSBackend::GetPossibleBreakpoints(Location *start, [[maybe_ return Error(Error::Type::INVALID_BREAKPOINT, "extractor not found"); } JSPtExtractor *extractor = GetExtractor(iter->second->GetUrl()); + if (extractor == nullptr) { + LOG(ERROR, DEBUGGER) << "GetPossibleBreakpoints: extractor is null"; + return Error(Error::Type::METHOD_NOT_FOUND, "Extractor not found"); + } int32_t line = start->GetLine(); int32_t column = start->GetColumn(); @@ -418,40 +424,19 @@ CString JSBackend::Trim(const CString &str) return ret; } -JSPtExtractor *JSBackend::GenerateExtractor(const JSPandaFile *jsPandaFile) -{ - const CString &fileName = jsPandaFile->GetJSPandaFileDesc(); - if (fileName.substr(0, DATA_APP_PATH.length()) != DATA_APP_PATH) { - return nullptr; - } - auto extractor = std::make_unique(jsPandaFile); - JSPtExtractor *res = extractor.get(); - extractors_[fileName] = std::move(extractor); - return res; -} - JSPtExtractor *JSBackend::GetExtractor(const JSPandaFile *jsPandaFile) { - const CString &fileName = jsPandaFile->GetJSPandaFileDesc(); - if (extractors_.find(fileName) == extractors_.end()) { - return nullptr; - } - - return extractors_[fileName].get(); + return JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile); } JSPtExtractor *JSBackend::GetExtractor(const CString &url) { - for (const auto &iter : extractors_) { - auto methods = iter.second->GetMethodIdList(); - for (const auto &method : methods) { - auto sourceFile = iter.second->GetSourceFile(method); - if (sourceFile == url) { - return iter.second.get(); - } - } + auto iter = extractors_.find(url); + if (iter == extractors_.end()) { + return nullptr; } - return nullptr; + + return iter->second; } bool JSBackend::GenerateCallFrames(CVector> *callFrames) diff --git a/ecmascript/tooling/agent/js_backend.h b/ecmascript/tooling/agent/js_backend.h index 60b0389709..485b56c5ec 100644 --- a/ecmascript/tooling/agent/js_backend.h +++ b/ecmascript/tooling/agent/js_backend.h @@ -134,7 +134,7 @@ private: const EcmaVM *ecmaVm_ {nullptr}; std::unique_ptr hooks_ {nullptr}; JSDebugger *debugger_ {nullptr}; - CUnorderedMap> extractors_ {}; + CUnorderedMap extractors_ {}; CUnorderedMap> scripts_ {}; CUnorderedMap> propertiesPair_ {}; RemoteObjectId curObjectId_ {0}; -- Gitee