Index: runtime/vm/metrics.cc |
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ad3859c7cd0ce3e726c73cec1600b26d41498fd9 |
--- /dev/null |
+++ b/runtime/vm/metrics.cc |
@@ -0,0 +1,197 @@ |
+// 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), |
+ value_(0), |
+ next_(NULL) { |
+} |
+ |
+ |
+void VMMetric::Init(Isolate* isolate, |
+ const char* name, |
+ const char* description) { |
+ isolate_ = isolate; |
+ name_ = name; |
+ description_ = description; |
+ RegisterWithIsolate(); |
+} |
+ |
+ |
+void VMMetric::Init(const char* name, const char* description) { |
+ name_ = name; |
+ description_ = description; |
+ RegisterWithVM(); |
+} |
+ |
+ |
+VMMetric::~VMMetric() { |
+ if (isolate_ == NULL) { |
+ DeregisterWithVM(); |
+ } else { |
+ DeregisterWithIsolate(); |
+ } |
+} |
+ |
+ |
+void VMMetric::PrintJSON(JSONStream* stream) { |
+ JSONObject obj(stream); |
+ obj.AddProperty("type", "Counter"); |
+ obj.AddProperty("name", name_); |
+ obj.AddProperty("description", description_); |
+ obj.AddPropertyF("id", "metrics/vm/%s", name_); |
+ // TODO(johnmccutchan): Overflow? |
+ double value_as_double = static_cast<double>(Value()); |
+ obj.AddProperty("value", value_as_double); |
+} |
+ |
+ |
+void VMMetric::RegisterWithIsolate() { |
+ 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() { |
+ 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_; |
+ // 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()); |
+ set_next(NULL); |
+ return; |
+ } |
+ ASSERT(head != NULL); |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+int64_t VMMetricHeapOldUsed::Value() const { |
+ Isolate* 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) \ |
+ 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) \ |
+ vm_metric_##variable##_.Init(name, NULL); |
+ VM_METRIC_LIST(VM_METRIC_INIT); |
+#undef VM_METRIC_INIT |
+} |
+ |
+} // namespace dart |