OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014, 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 #include "vm/metrics.h" | |
6 | |
7 #include "vm/isolate.h" | |
8 #include "vm/json_stream.h" | |
9 #include "vm/native_entry.h" | |
10 #include "vm/runtime_entry.h" | |
11 #include "vm/object.h" | |
12 | |
13 namespace dart { | |
14 | |
15 VMMetric* VMMetric::vm_list_head_ = NULL; | |
16 | |
17 VMMetric::VMMetric() | |
18 : isolate_(NULL), | |
19 name_(NULL), | |
20 description_(NULL), | |
21 unit_(kCounter), | |
22 value_(0), | |
23 next_(NULL) { | |
24 } | |
25 | |
26 | |
27 void VMMetric::Init(Isolate* isolate, | |
28 const char* name, | |
29 const char* description, | |
30 Unit unit) { | |
koda
2014/08/13 22:42:59
Assert Init is called only once.
Cutch
2014/08/14 20:56:19
Done.
| |
31 isolate_ = isolate; | |
32 name_ = name; | |
33 description_ = description; | |
34 unit_ = unit; | |
35 RegisterWithIsolate(); | |
36 } | |
37 | |
38 | |
39 void VMMetric::Init(const char* name, const char* description, Unit unit) { | |
40 name_ = name; | |
41 description_ = description; | |
42 unit_ = unit; | |
43 RegisterWithVM(); | |
44 } | |
45 | |
46 | |
47 VMMetric::~VMMetric() { | |
48 if (isolate_ == NULL) { | |
49 DeregisterWithVM(); | |
50 } else { | |
51 DeregisterWithIsolate(); | |
52 } | |
53 } | |
54 | |
55 | |
56 static const char* UnitString(intptr_t unit) { | |
57 switch (unit) { | |
58 case VMMetric::kCounter: return "counter"; | |
koda
2014/08/13 22:42:59
I suppose this mapping will need to be sync'ed wit
Cutch
2014/08/14 20:56:19
Acknowledged.
| |
59 case VMMetric::kByte: return "byte"; | |
60 default: | |
61 UNREACHABLE(); | |
62 } | |
63 UNREACHABLE(); | |
64 return NULL; | |
65 } | |
66 | |
67 | |
68 void VMMetric::PrintJSON(JSONStream* stream) { | |
69 JSONObject obj(stream); | |
70 obj.AddProperty("type", "Counter"); | |
71 obj.AddProperty("name", name_); | |
72 obj.AddProperty("description", description_); | |
73 obj.AddProperty("unit", UnitString(unit())); | |
74 obj.AddPropertyF("id", "metrics/vm/%s", name_); | |
koda
2014/08/13 22:42:59
There is nothing that distinguishes per-isolate me
Cutch
2014/08/14 20:56:18
It is distinguished in libservice by the Metric's
| |
75 // TODO(johnmccutchan): Overflow? | |
76 double value_as_double = static_cast<double>(Value()); | |
77 obj.AddProperty("value", value_as_double); | |
78 } | |
79 | |
80 | |
81 void VMMetric::RegisterWithIsolate() { | |
koda
2014/08/13 22:42:59
Assert no duplicate registration?
Cutch
2014/08/14 20:56:19
Done.
| |
82 ASSERT(isolate_ != NULL); | |
83 ASSERT(next_ == NULL); | |
84 VMMetric* head = isolate_->metrics_list_head(); | |
85 if (head != NULL) { | |
86 set_next(head); | |
87 } | |
88 isolate_->set_metrics_list_head(this); | |
89 } | |
90 | |
91 | |
92 void VMMetric::DeregisterWithIsolate() { | |
93 VMMetric* head = isolate_->metrics_list_head(); | |
94 ASSERT(head != NULL); | |
95 // Handle head of list case. | |
96 if (head == this) { | |
97 isolate_->set_metrics_list_head(next()); | |
98 set_next(NULL); | |
99 return; | |
100 } | |
101 VMMetric* previous = NULL; | |
102 while (true) { | |
103 previous = head; | |
104 ASSERT(previous != NULL); | |
105 head = head->next(); | |
106 if (head == NULL) { | |
107 break; | |
108 } | |
109 if (head == this) { | |
110 // Remove this from list. | |
111 previous->set_next(head->next()); | |
112 set_next(NULL); | |
113 return; | |
114 } | |
115 ASSERT(head != NULL); | |
116 } | |
117 UNREACHABLE(); | |
118 } | |
119 | |
120 | |
121 void VMMetric::RegisterWithVM() { | |
koda
2014/08/13 22:42:59
Ditto.
Cutch
2014/08/14 20:56:18
Done.
| |
122 ASSERT(isolate_ == NULL); | |
123 ASSERT(next_ == NULL); | |
124 VMMetric* head = vm_list_head_; | |
125 if (head != NULL) { | |
126 set_next(head); | |
127 } | |
128 vm_list_head_ = this; | |
129 } | |
130 | |
131 | |
132 void VMMetric::DeregisterWithVM() { | |
133 ASSERT(isolate_ == NULL); | |
134 VMMetric* head = vm_list_head_; | |
135 if (head == NULL) { | |
136 return; | |
137 } | |
138 // Handle head of list case. | |
139 if (head == this) { | |
140 vm_list_head_ = next(); | |
141 set_next(NULL); | |
142 return; | |
143 } | |
144 VMMetric* previous = NULL; | |
145 while (true) { | |
146 previous = head; | |
147 ASSERT(previous != NULL); | |
148 head = head->next(); | |
149 if (head == NULL) { | |
150 break; | |
151 } | |
152 if (head == this) { | |
153 // Remove this from list. | |
154 previous->set_next(head->next()); | |
koda
2014/08/13 22:42:59
Just a general observation: we have lots of linked
Cutch
2014/08/14 20:56:18
Acknowledged.
| |
155 set_next(NULL); | |
156 return; | |
157 } | |
158 ASSERT(head != NULL); | |
159 } | |
160 UNREACHABLE(); | |
161 } | |
162 | |
163 | |
164 int64_t VMMetricHeapOldUsed::Value() const { | |
165 Isolate* isolate = Isolate::Current(); | |
koda
2014/08/13 22:42:59
Shouldn't these all use "isolate_" rather than the
Cutch
2014/08/14 20:56:18
Done and also ASSERT(isolate() == Isolate::Current
| |
166 return isolate->heap()->UsedInWords(Heap::kOld) * kWordSize; | |
167 } | |
168 | |
169 | |
170 int64_t VMMetricHeapOldCapacity::Value() const { | |
171 Isolate* isolate = Isolate::Current(); | |
172 return isolate->heap()->CapacityInWords(Heap::kOld) * kWordSize; | |
173 } | |
174 | |
175 | |
176 int64_t VMMetricHeapOldExternal::Value() const { | |
177 Isolate* isolate = Isolate::Current(); | |
178 return isolate->heap()->ExternalInWords(Heap::kOld) * kWordSize; | |
179 } | |
180 | |
181 | |
182 int64_t VMMetricHeapNewUsed::Value() const { | |
183 Isolate* isolate = Isolate::Current(); | |
184 return isolate->heap()->UsedInWords(Heap::kNew) * kWordSize; | |
185 } | |
186 | |
187 | |
188 int64_t VMMetricHeapNewCapacity::Value() const { | |
189 Isolate* isolate = Isolate::Current(); | |
190 return isolate->heap()->CapacityInWords(Heap::kNew) * kWordSize; | |
191 } | |
192 | |
193 | |
194 int64_t VMMetricHeapNewExternal::Value() const { | |
195 Isolate* isolate = Isolate::Current(); | |
196 return isolate->heap()->ExternalInWords(Heap::kNew) * kWordSize; | |
197 } | |
198 | |
199 | |
200 int64_t VMMetricIsolateCount::Value() const { | |
201 return Isolate::IsolateListLength(); | |
202 } | |
203 | |
204 #define VM_METRIC_VARIABLE(type, variable, name, unit) \ | |
205 static type vm_metric_##variable##_; | |
206 VM_METRIC_LIST(VM_METRIC_VARIABLE); | |
207 #undef VM_METRIC_VARIABLE | |
208 | |
209 | |
210 void VMMetric::InitOnce() { | |
211 #define VM_METRIC_INIT(type, variable, name, unit) \ | |
212 vm_metric_##variable##_.Init(name, NULL, VMMetric::unit); | |
213 VM_METRIC_LIST(VM_METRIC_INIT); | |
214 #undef VM_METRIC_INIT | |
215 } | |
216 | |
217 } // namespace dart | |
OLD | NEW |