| // 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 { | 
 |  | 
 | // 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, | 
 |   }; | 
 |  | 
 |   static const char* kCallSitesStr; | 
 |   static const char* kCoverageStr; | 
 |   static const char* kPossibleBreakpointsStr; | 
 |   static const char* kProfileStr; | 
 |  | 
 |   enum CompileMode { kNoCompile, kForceCompile }; | 
 |  | 
 |   // report_set is a bitvector indicating which reports to generate | 
 |   // (e.g. kCallSites | kCoverage). | 
 |   explicit SourceReport(intptr_t report_set, | 
 |                         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); | 
 |   intptr_t GetTokenPosOrLine(const Script& script, | 
 |                              const TokenPosition& token_pos); | 
 |  | 
 |   void PrintCallSitesData(JSONObject* jsobj, | 
 |                           const Function& func, | 
 |                           const Code& code); | 
 |   void PrintCoverageData(JSONObject* jsobj, | 
 |                          const Function& func, | 
 |                          const Code& code); | 
 |   void PrintPossibleBreakpointsData(JSONObject* jsobj, | 
 |                                     const Function& func, | 
 |                                     const Code& code); | 
 |   void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function); | 
 | #if defined(DEBUG) | 
 |   void VerifyScriptTable(); | 
 | #endif | 
 |   void PrintScriptTable(JSONArray* jsarr); | 
 |  | 
 |   void VisitFunction(JSONArray* jsarr, const Function& func); | 
 |   void VisitField(JSONArray* jsarr, const Field& field); | 
 |   void VisitLibrary(JSONArray* jsarr, const Library& lib); | 
 |   void VisitClosures(JSONArray* jsarr); | 
 |   // An entry in the script table. | 
 |   struct ScriptTableEntry { | 
 |     ScriptTableEntry() : key(NULL), index(-1), script(NULL) {} | 
 |  | 
 |     const String* key; | 
 |     intptr_t index; | 
 |     const Script* script; | 
 |   }; | 
 |  | 
 |   // 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, | 
 |       JSONArray* ranges); | 
 |  | 
 |   intptr_t report_set_; | 
 |   CompileMode compile_mode_; | 
 |   bool report_lines_; | 
 |   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_; | 
 | }; | 
 |  | 
 | }  // namespace dart | 
 |  | 
 | #endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | 
 | #endif  // RUNTIME_VM_SOURCE_REPORT_H_ |