Chromium Code Reviews| 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 |