Index: runtime/vm/metrics.cc |
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..483bd531974c13f0320bb01d1a0f99d99e73d2cb |
--- /dev/null |
+++ b/runtime/vm/metrics.cc |
@@ -0,0 +1,217 @@ |
+// Copyright (c) 2014, 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. |
+ |
+#include "vm/metrics.h" |
+ |
+#include "vm/isolate.h" |
+#include "vm/json_stream.h" |
+#include "vm/native_entry.h" |
+#include "vm/runtime_entry.h" |
+#include "vm/object.h" |
+ |
+namespace dart { |
+ |
+VMMetric* VMMetric::vm_list_head_ = NULL; |
+ |
+VMMetric::VMMetric() |
+ : isolate_(NULL), |
+ name_(NULL), |
+ description_(NULL), |
+ unit_(kCounter), |
+ value_(0), |
+ next_(NULL) { |
+} |
+ |
+ |
+void VMMetric::Init(Isolate* isolate, |
+ const char* name, |
+ const char* description, |
+ Unit unit) { |
koda
2014/08/13 22:42:59
Assert Init is called only once.
Cutch
2014/08/14 20:56:19
Done.
|
+ isolate_ = isolate; |
+ name_ = name; |
+ description_ = description; |
+ unit_ = unit; |
+ RegisterWithIsolate(); |
+} |
+ |
+ |
+void VMMetric::Init(const char* name, const char* description, Unit unit) { |
+ name_ = name; |
+ description_ = description; |
+ unit_ = unit; |
+ RegisterWithVM(); |
+} |
+ |
+ |
+VMMetric::~VMMetric() { |
+ if (isolate_ == NULL) { |
+ DeregisterWithVM(); |
+ } else { |
+ DeregisterWithIsolate(); |
+ } |
+} |
+ |
+ |
+static const char* UnitString(intptr_t unit) { |
+ switch (unit) { |
+ 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.
|
+ case VMMetric::kByte: return "byte"; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ UNREACHABLE(); |
+ return NULL; |
+} |
+ |
+ |
+void VMMetric::PrintJSON(JSONStream* stream) { |
+ JSONObject obj(stream); |
+ obj.AddProperty("type", "Counter"); |
+ obj.AddProperty("name", name_); |
+ obj.AddProperty("description", description_); |
+ obj.AddProperty("unit", UnitString(unit())); |
+ 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
|
+ // TODO(johnmccutchan): Overflow? |
+ double value_as_double = static_cast<double>(Value()); |
+ obj.AddProperty("value", value_as_double); |
+} |
+ |
+ |
+void VMMetric::RegisterWithIsolate() { |
koda
2014/08/13 22:42:59
Assert no duplicate registration?
Cutch
2014/08/14 20:56:19
Done.
|
+ ASSERT(isolate_ != NULL); |
+ ASSERT(next_ == NULL); |
+ VMMetric* head = isolate_->metrics_list_head(); |
+ if (head != NULL) { |
+ set_next(head); |
+ } |
+ isolate_->set_metrics_list_head(this); |
+} |
+ |
+ |
+void VMMetric::DeregisterWithIsolate() { |
+ VMMetric* head = isolate_->metrics_list_head(); |
+ ASSERT(head != NULL); |
+ // Handle head of list case. |
+ if (head == this) { |
+ isolate_->set_metrics_list_head(next()); |
+ set_next(NULL); |
+ return; |
+ } |
+ VMMetric* previous = NULL; |
+ while (true) { |
+ previous = head; |
+ ASSERT(previous != NULL); |
+ head = head->next(); |
+ if (head == NULL) { |
+ break; |
+ } |
+ if (head == this) { |
+ // Remove this from list. |
+ previous->set_next(head->next()); |
+ set_next(NULL); |
+ return; |
+ } |
+ ASSERT(head != NULL); |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+void VMMetric::RegisterWithVM() { |
koda
2014/08/13 22:42:59
Ditto.
Cutch
2014/08/14 20:56:18
Done.
|
+ ASSERT(isolate_ == NULL); |
+ ASSERT(next_ == NULL); |
+ VMMetric* head = vm_list_head_; |
+ if (head != NULL) { |
+ set_next(head); |
+ } |
+ vm_list_head_ = this; |
+} |
+ |
+ |
+void VMMetric::DeregisterWithVM() { |
+ ASSERT(isolate_ == NULL); |
+ VMMetric* head = vm_list_head_; |
+ if (head == NULL) { |
+ return; |
+ } |
+ // Handle head of list case. |
+ if (head == this) { |
+ vm_list_head_ = next(); |
+ set_next(NULL); |
+ return; |
+ } |
+ VMMetric* previous = NULL; |
+ while (true) { |
+ previous = head; |
+ ASSERT(previous != NULL); |
+ head = head->next(); |
+ if (head == NULL) { |
+ break; |
+ } |
+ if (head == this) { |
+ // Remove this from list. |
+ 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.
|
+ set_next(NULL); |
+ return; |
+ } |
+ ASSERT(head != NULL); |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+int64_t VMMetricHeapOldUsed::Value() const { |
+ 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
|
+ return isolate->heap()->UsedInWords(Heap::kOld) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricHeapOldCapacity::Value() const { |
+ Isolate* isolate = Isolate::Current(); |
+ return isolate->heap()->CapacityInWords(Heap::kOld) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricHeapOldExternal::Value() const { |
+ Isolate* isolate = Isolate::Current(); |
+ return isolate->heap()->ExternalInWords(Heap::kOld) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricHeapNewUsed::Value() const { |
+ Isolate* isolate = Isolate::Current(); |
+ return isolate->heap()->UsedInWords(Heap::kNew) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricHeapNewCapacity::Value() const { |
+ Isolate* isolate = Isolate::Current(); |
+ return isolate->heap()->CapacityInWords(Heap::kNew) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricHeapNewExternal::Value() const { |
+ Isolate* isolate = Isolate::Current(); |
+ return isolate->heap()->ExternalInWords(Heap::kNew) * kWordSize; |
+} |
+ |
+ |
+int64_t VMMetricIsolateCount::Value() const { |
+ return Isolate::IsolateListLength(); |
+} |
+ |
+#define VM_METRIC_VARIABLE(type, variable, name, unit) \ |
+ static type vm_metric_##variable##_; |
+ VM_METRIC_LIST(VM_METRIC_VARIABLE); |
+#undef VM_METRIC_VARIABLE |
+ |
+ |
+void VMMetric::InitOnce() { |
+#define VM_METRIC_INIT(type, variable, name, unit) \ |
+ vm_metric_##variable##_.Init(name, NULL, VMMetric::unit); |
+ VM_METRIC_LIST(VM_METRIC_INIT); |
+#undef VM_METRIC_INIT |
+} |
+ |
+} // namespace dart |