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 Metric* Metric::vm_list_head_ = NULL; |
| 16 |
| 17 Metric::Metric() |
| 18 : isolate_(NULL), |
| 19 name_(NULL), |
| 20 description_(NULL), |
| 21 unit_(kCounter), |
| 22 value_(0), |
| 23 next_(NULL) { |
| 24 } |
| 25 |
| 26 |
| 27 void Metric::Init(Isolate* isolate, |
| 28 const char* name, |
| 29 const char* description, |
| 30 Unit unit) { |
| 31 // Only called once. |
| 32 ASSERT(next_ == NULL); |
| 33 ASSERT(name != NULL); |
| 34 isolate_ = isolate; |
| 35 name_ = name; |
| 36 description_ = description; |
| 37 unit_ = unit; |
| 38 RegisterWithIsolate(); |
| 39 } |
| 40 |
| 41 |
| 42 void Metric::Init(const char* name, const char* description, Unit unit) { |
| 43 // Only called once. |
| 44 ASSERT(next_ == NULL); |
| 45 ASSERT(name != NULL); |
| 46 name_ = name; |
| 47 description_ = description; |
| 48 unit_ = unit; |
| 49 RegisterWithVM(); |
| 50 } |
| 51 |
| 52 |
| 53 Metric::~Metric() { |
| 54 if (isolate_ == NULL) { |
| 55 DeregisterWithVM(); |
| 56 } else { |
| 57 DeregisterWithIsolate(); |
| 58 } |
| 59 } |
| 60 |
| 61 |
| 62 static const char* UnitString(intptr_t unit) { |
| 63 switch (unit) { |
| 64 case Metric::kCounter: return "counter"; |
| 65 case Metric::kByte: return "byte"; |
| 66 default: |
| 67 UNREACHABLE(); |
| 68 } |
| 69 UNREACHABLE(); |
| 70 return NULL; |
| 71 } |
| 72 |
| 73 |
| 74 void Metric::PrintJSON(JSONStream* stream) { |
| 75 JSONObject obj(stream); |
| 76 obj.AddProperty("type", "Counter"); |
| 77 obj.AddProperty("name", name_); |
| 78 obj.AddProperty("description", description_); |
| 79 obj.AddProperty("unit", UnitString(unit())); |
| 80 obj.AddPropertyF("id", "metrics/vm/%s", name_); |
| 81 // TODO(johnmccutchan): Overflow? |
| 82 double value_as_double = static_cast<double>(Value()); |
| 83 obj.AddProperty("value", value_as_double); |
| 84 } |
| 85 |
| 86 |
| 87 bool Metric::NameExists(Metric* head, const char* name) { |
| 88 ASSERT(name != NULL); |
| 89 while (head != NULL) { |
| 90 const char* metric_name = head->name(); |
| 91 ASSERT(metric_name != NULL); |
| 92 if (strcmp(metric_name, name) == 0) { |
| 93 return true; |
| 94 } |
| 95 head = head->next(); |
| 96 } |
| 97 return false; |
| 98 } |
| 99 |
| 100 |
| 101 |
| 102 void Metric::RegisterWithIsolate() { |
| 103 ASSERT(isolate_ != NULL); |
| 104 ASSERT(next_ == NULL); |
| 105 // No duplicate names allowed. |
| 106 ASSERT(!NameExists(isolate_->metrics_list_head(), name())); |
| 107 Metric* head = isolate_->metrics_list_head(); |
| 108 if (head != NULL) { |
| 109 set_next(head); |
| 110 } |
| 111 isolate_->set_metrics_list_head(this); |
| 112 } |
| 113 |
| 114 |
| 115 void Metric::DeregisterWithIsolate() { |
| 116 Metric* head = isolate_->metrics_list_head(); |
| 117 ASSERT(head != NULL); |
| 118 // Handle head of list case. |
| 119 if (head == this) { |
| 120 isolate_->set_metrics_list_head(next()); |
| 121 set_next(NULL); |
| 122 return; |
| 123 } |
| 124 Metric* previous = NULL; |
| 125 while (true) { |
| 126 previous = head; |
| 127 ASSERT(previous != NULL); |
| 128 head = head->next(); |
| 129 if (head == NULL) { |
| 130 break; |
| 131 } |
| 132 if (head == this) { |
| 133 // Remove this from list. |
| 134 previous->set_next(head->next()); |
| 135 set_next(NULL); |
| 136 return; |
| 137 } |
| 138 ASSERT(head != NULL); |
| 139 } |
| 140 UNREACHABLE(); |
| 141 } |
| 142 |
| 143 |
| 144 void Metric::RegisterWithVM() { |
| 145 ASSERT(isolate_ == NULL); |
| 146 ASSERT(next_ == NULL); |
| 147 // No duplicate names allowed. |
| 148 ASSERT(!NameExists(vm_list_head_, name())); |
| 149 Metric* head = vm_list_head_; |
| 150 if (head != NULL) { |
| 151 set_next(head); |
| 152 } |
| 153 vm_list_head_ = this; |
| 154 } |
| 155 |
| 156 |
| 157 void Metric::DeregisterWithVM() { |
| 158 ASSERT(isolate_ == NULL); |
| 159 Metric* head = vm_list_head_; |
| 160 if (head == NULL) { |
| 161 return; |
| 162 } |
| 163 // Handle head of list case. |
| 164 if (head == this) { |
| 165 vm_list_head_ = next(); |
| 166 set_next(NULL); |
| 167 return; |
| 168 } |
| 169 Metric* previous = NULL; |
| 170 while (true) { |
| 171 previous = head; |
| 172 ASSERT(previous != NULL); |
| 173 head = head->next(); |
| 174 if (head == NULL) { |
| 175 break; |
| 176 } |
| 177 if (head == this) { |
| 178 // Remove this from list. |
| 179 previous->set_next(head->next()); |
| 180 set_next(NULL); |
| 181 return; |
| 182 } |
| 183 ASSERT(head != NULL); |
| 184 } |
| 185 UNREACHABLE(); |
| 186 } |
| 187 |
| 188 |
| 189 int64_t MetricHeapOldUsed::Value() const { |
| 190 ASSERT(isolate() == Isolate::Current()); |
| 191 return isolate()->heap()->UsedInWords(Heap::kOld) * kWordSize; |
| 192 } |
| 193 |
| 194 |
| 195 int64_t MetricHeapOldCapacity::Value() const { |
| 196 ASSERT(isolate() == Isolate::Current()); |
| 197 return isolate()->heap()->CapacityInWords(Heap::kOld) * kWordSize; |
| 198 } |
| 199 |
| 200 |
| 201 int64_t MetricHeapOldExternal::Value() const { |
| 202 ASSERT(isolate() == Isolate::Current()); |
| 203 return isolate()->heap()->ExternalInWords(Heap::kOld) * kWordSize; |
| 204 } |
| 205 |
| 206 |
| 207 int64_t MetricHeapNewUsed::Value() const { |
| 208 ASSERT(isolate() == Isolate::Current()); |
| 209 return isolate()->heap()->UsedInWords(Heap::kNew) * kWordSize; |
| 210 } |
| 211 |
| 212 |
| 213 int64_t MetricHeapNewCapacity::Value() const { |
| 214 ASSERT(isolate() == Isolate::Current()); |
| 215 return isolate()->heap()->CapacityInWords(Heap::kNew) * kWordSize; |
| 216 } |
| 217 |
| 218 |
| 219 int64_t MetricHeapNewExternal::Value() const { |
| 220 ASSERT(isolate() == Isolate::Current()); |
| 221 return isolate()->heap()->ExternalInWords(Heap::kNew) * kWordSize; |
| 222 } |
| 223 |
| 224 |
| 225 int64_t MetricIsolateCount::Value() const { |
| 226 return Isolate::IsolateListLength(); |
| 227 } |
| 228 |
| 229 #define VM_METRIC_VARIABLE(type, variable, name, unit) \ |
| 230 static type vm_metric_##variable##_; |
| 231 VM_METRIC_LIST(VM_METRIC_VARIABLE); |
| 232 #undef VM_METRIC_VARIABLE |
| 233 |
| 234 |
| 235 void Metric::InitOnce() { |
| 236 #define VM_METRIC_INIT(type, variable, name, unit) \ |
| 237 vm_metric_##variable##_.Init(name, NULL, Metric::unit); |
| 238 VM_METRIC_LIST(VM_METRIC_INIT); |
| 239 #undef VM_METRIC_INIT |
| 240 } |
| 241 |
| 242 } // namespace dart |
OLD | NEW |