| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #ifndef RUNTIME_VM_SOURCE_REPORT_H_ | |
| #define RUNTIME_VM_SOURCE_REPORT_H_ | |
| #include "vm/globals.h" | |
| #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | |
| #include "vm/allocation.h" | |
| #include "vm/flags.h" | |
| #include "vm/hash_map.h" | |
| #include "vm/object.h" | |
| #include "vm/profiler_service.h" | |
| #include "vm/token_position.h" | |
| namespace dart { | |
| struct SourceReportCodeInfo; | |
| // A SourceReport object is used to generate reports about the program | |
| // source code, with information associated with source token | |
| // positions. There are multiple possible kinds of reports. | |
| class SourceReport { | |
| public: | |
| enum ReportKind { | |
| kCallSites = 0x1, | |
| kCoverage = 0x2, | |
| kPossibleBreakpoints = 0x4, | |
| kProfile = 0x8, | |
| kBranchCoverage = 0x10, | |
| }; | |
| static const char* kCallSitesStr; | |
| static const char* kCoverageStr; | |
| static const char* kPossibleBreakpointsStr; | |
| static const char* kProfileStr; | |
| static const char* kBranchCoverageStr; | |
| enum CompileMode { kNoCompile, kForceCompile }; | |
| // report_set is a bitvector indicating which reports to generate | |
| // (e.g. kCallSites | kCoverage). | |
| // | |
| // If library_filters is not null, then the report will only include libraries | |
| // whose URIs start with one of the filter strings. | |
| explicit SourceReport(intptr_t report_set, | |
| CompileMode compile = kNoCompile, | |
| bool report_lines = false); | |
| explicit SourceReport(intptr_t report_set, | |
| const GrowableObjectArray& library_filters, | |
| ZoneCStringSet* libraries_already_compiled = nullptr, | |
| CompileMode compile = kNoCompile, | |
| bool report_lines = false); | |
| ~SourceReport(); | |
| // Generate a source report for (some subrange of) a script. | |
| // | |
| // If script is null, then the report is generated for all scripts | |
| // in the isolate. | |
| void PrintJSON(JSONStream* js, | |
| const Script& script, | |
| TokenPosition start_pos = TokenPosition::kMinSource, | |
| TokenPosition end_pos = TokenPosition::kMaxSource); | |
| private: | |
| void ClearScriptTable(); | |
| void Init(Thread* thread, | |
| const Script* script, | |
| TokenPosition start_pos, | |
| TokenPosition end_pos); | |
| Thread* thread() const { return thread_; } | |
| Zone* zone() const { return thread_->zone(); } | |
| Isolate* isolate() const { return thread_->isolate(); } | |
| bool IsReportRequested(ReportKind report_kind); | |
| bool ShouldSkipFunction(const Function& func); | |
| bool ShouldSkipField(const Field& field); | |
| intptr_t GetScriptIndex(const Script& script); | |
| bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib); | |
| bool IsLibraryAlreadyCompiled(const Library& lib); | |
| bool ShouldFiltersIncludeScript(const Script& script); | |
| bool ShouldFiltersIncludeUrl(const String& url); | |
| void PrintCallSitesData(JSONObject* jsobj, | |
| const SourceReportCodeInfo& params); | |
| void PrintCoverageData(JSONObject* jsobj, | |
| const SourceReportCodeInfo& params, | |
| bool report_branch_coverage); | |
| void PrintPossibleBreakpointsData(JSONObject* jsobj, | |
| const SourceReportCodeInfo& params); | |
| void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function); | |
| #if defined(DEBUG) | |
| void VerifyScriptTable(); | |
| #endif | |
| void PrintScriptTable(JSONArray* jsarr); | |
| void VisitFunction(JSONArray* jsarr, | |
| const Function& func, | |
| CompileMode compile_mode); | |
| void VisitField(JSONArray* jsarr, | |
| const Field& field, | |
| CompileMode compile_mode); | |
| void VisitLibrary(JSONArray* jsarr, const Library& lib); | |
| void VisitClosures(JSONArray* jsarr); | |
| // An entry in the script table. | |
| struct ScriptTableEntry { | |
| ScriptTableEntry() : key(nullptr), index(-1), script(nullptr) {} | |
| const String* key; | |
| intptr_t index; | |
| const Script* script; | |
| GrowableArray<TokenPosition> const_constructor_hits; | |
| }; | |
| // Needed for DirectChainedHashMap. | |
| struct ScriptTableTrait { | |
| typedef ScriptTableEntry* Value; | |
| typedef const ScriptTableEntry* Key; | |
| typedef ScriptTableEntry* Pair; | |
| static Key KeyOf(Pair kv) { return kv; } | |
| static Value ValueOf(Pair kv) { return kv; } | |
| static inline uword Hash(Key key) { return key->key->Hash(); } | |
| static inline bool IsKeyEqual(Pair kv, Key key) { | |
| return kv->script->ptr() == key->script->ptr(); | |
| } | |
| }; | |
| void CollectAllScripts( | |
| DirectChainedHashMap<ScriptTableTrait>* local_script_table, | |
| GrowableArray<ScriptTableEntry*>* local_script_table_entries); | |
| void CleanupCollectedScripts( | |
| DirectChainedHashMap<ScriptTableTrait>* local_script_table, | |
| GrowableArray<ScriptTableEntry*>* local_script_table_entries); | |
| void CollectConstConstructorCoverageFromScripts( | |
| GrowableArray<ScriptTableEntry*>* local_script_table_entries); | |
| intptr_t report_set_; | |
| CompileMode compile_mode_; | |
| bool report_lines_; | |
| const GrowableObjectArray& library_filters_; | |
| ZoneCStringSet* libraries_already_compiled_; | |
| Thread* thread_; | |
| const Script* script_; | |
| TokenPosition start_pos_; | |
| TokenPosition end_pos_; | |
| Profile profile_; | |
| GrowableArray<ScriptTableEntry*> script_table_entries_; | |
| DirectChainedHashMap<ScriptTableTrait> script_table_; | |
| intptr_t next_script_index_; | |
| intptr_t late_error_class_id_ = ClassId::kIllegalCid; | |
| }; | |
| } // namespace dart | |
| #endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | |
| #endif // RUNTIME_VM_SOURCE_REPORT_H_ |