1// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_SOURCE_REPORT_H_
6#define RUNTIME_VM_SOURCE_REPORT_H_
7
8#include "vm/globals.h"
9#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
10
11#include "vm/allocation.h"
12#include "vm/flags.h"
13#include "vm/hash_map.h"
14#include "vm/object.h"
15#include "vm/profiler_service.h"
16#include "vm/token_position.h"
17
18namespace dart {
19
20// A SourceReport object is used to generate reports about the program
21// source code, with information associated with source token
22// positions. There are multiple possible kinds of reports.
23class SourceReport {
24 public:
25 enum ReportKind {
26 kCallSites = 0x1,
27 kCoverage = 0x2,
28 kPossibleBreakpoints = 0x4,
29 kProfile = 0x8,
30 };
31
32 static const char* kCallSitesStr;
33 static const char* kCoverageStr;
34 static const char* kPossibleBreakpointsStr;
35 static const char* kProfileStr;
36
37 enum CompileMode { kNoCompile, kForceCompile };
38
39 // report_set is a bitvector indicating which reports to generate
40 // (e.g. kCallSites | kCoverage).
41 explicit SourceReport(intptr_t report_set, CompileMode compile = kNoCompile);
42 ~SourceReport();
43
44 // Generate a source report for (some subrange of) a script.
45 //
46 // If script is null, then the report is generated for all scripts
47 // in the isolate.
48 void PrintJSON(JSONStream* js,
49 const Script& script,
50 TokenPosition start_pos = TokenPosition::kNoSource,
51 TokenPosition end_pos = TokenPosition::kNoSource);
52
53 private:
54 void ClearScriptTable();
55 void Init(Thread* thread,
56 const Script* script,
57 TokenPosition start_pos,
58 TokenPosition end_pos);
59
60 Thread* thread() const { return thread_; }
61 Zone* zone() const { return thread_->zone(); }
62 Isolate* isolate() const { return thread_->isolate(); }
63
64 bool IsReportRequested(ReportKind report_kind);
65 bool ShouldSkipFunction(const Function& func);
66 bool ShouldSkipField(const Field& field);
67 intptr_t GetScriptIndex(const Script& script);
68 bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
69
70 void PrintCallSitesData(JSONObject* jsobj,
71 const Function& func,
72 const Code& code);
73 void PrintCoverageData(JSONObject* jsobj,
74 const Function& func,
75 const Code& code);
76 void PrintPossibleBreakpointsData(JSONObject* jsobj,
77 const Function& func,
78 const Code& code);
79 void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function);
80#if defined(DEBUG)
81 void VerifyScriptTable();
82#endif
83 void PrintScriptTable(JSONArray* jsarr);
84
85 void VisitFunction(JSONArray* jsarr, const Function& func);
86 void VisitField(JSONArray* jsarr, const Field& field);
87 void VisitLibrary(JSONArray* jsarr, const Library& lib);
88 void VisitClosures(JSONArray* jsarr);
89 // An entry in the script table.
90 struct ScriptTableEntry {
91 ScriptTableEntry() : key(NULL), index(-1), script(NULL) {}
92
93 const String* key;
94 intptr_t index;
95 const Script* script;
96 };
97
98 // Needed for DirectChainedHashMap.
99 struct ScriptTableTrait {
100 typedef ScriptTableEntry* Value;
101 typedef const ScriptTableEntry* Key;
102 typedef ScriptTableEntry* Pair;
103
104 static Key KeyOf(Pair kv) { return kv; }
105
106 static Value ValueOf(Pair kv) { return kv; }
107
108 static inline intptr_t Hashcode(Key key) { return key->key->Hash(); }
109
110 static inline bool IsKeyEqual(Pair kv, Key key) {
111 return kv->script->raw() == key->script->raw();
112 }
113 };
114
115 intptr_t report_set_;
116 CompileMode compile_mode_;
117 Thread* thread_;
118 const Script* script_;
119 TokenPosition start_pos_;
120 TokenPosition end_pos_;
121 Profile profile_;
122 GrowableArray<ScriptTableEntry*> script_table_entries_;
123 DirectChainedHashMap<ScriptTableTrait> script_table_;
124 intptr_t next_script_index_;
125};
126
127} // namespace dart
128
129#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
130#endif // RUNTIME_VM_SOURCE_REPORT_H_
131