Line data Source code
1 : // Copyright 2012 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/extensions/statistics-extension.h"
6 :
7 : #include "src/counters.h"
8 : #include "src/heap/heap-inl.h"
9 : #include "src/isolate.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : const char* const StatisticsExtension::kSource =
15 : "native function getV8Statistics();";
16 :
17 :
18 0 : v8::Local<v8::FunctionTemplate> StatisticsExtension::GetNativeFunctionTemplate(
19 : v8::Isolate* isolate, v8::Local<v8::String> str) {
20 : DCHECK(strcmp(*v8::String::Utf8Value(str), "getV8Statistics") == 0);
21 0 : return v8::FunctionTemplate::New(isolate, StatisticsExtension::GetCounters);
22 : }
23 :
24 :
25 0 : static void AddCounter(v8::Isolate* isolate,
26 : v8::Local<v8::Object> object,
27 : StatsCounter* counter,
28 : const char* name) {
29 0 : if (counter->Enabled()) {
30 : object->Set(isolate->GetCurrentContext(),
31 : v8::String::NewFromUtf8(isolate, name, NewStringType::kNormal)
32 : .ToLocalChecked(),
33 0 : v8::Number::New(isolate, *counter->GetInternalPointer()))
34 0 : .FromJust();
35 : }
36 0 : }
37 :
38 0 : static void AddNumber(v8::Isolate* isolate, v8::Local<v8::Object> object,
39 : double value, const char* name) {
40 : object
41 : ->Set(isolate->GetCurrentContext(),
42 : v8::String::NewFromUtf8(isolate, name, NewStringType::kNormal)
43 : .ToLocalChecked(),
44 0 : v8::Number::New(isolate, value))
45 0 : .FromJust();
46 0 : }
47 :
48 :
49 0 : static void AddNumber64(v8::Isolate* isolate,
50 : v8::Local<v8::Object> object,
51 : int64_t value,
52 : const char* name) {
53 : object->Set(isolate->GetCurrentContext(),
54 : v8::String::NewFromUtf8(isolate, name, NewStringType::kNormal)
55 : .ToLocalChecked(),
56 0 : v8::Number::New(isolate, static_cast<double>(value))).FromJust();
57 0 : }
58 :
59 :
60 0 : void StatisticsExtension::GetCounters(
61 0 : const v8::FunctionCallbackInfo<v8::Value>& args) {
62 0 : Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate());
63 0 : Heap* heap = isolate->heap();
64 :
65 0 : if (args.Length() > 0) { // GC if first argument evaluates to true.
66 0 : if (args[0]->IsBoolean() &&
67 : args[0]
68 0 : ->BooleanValue(args.GetIsolate()->GetCurrentContext())
69 0 : .FromMaybe(false)) {
70 : heap->CollectAllGarbage(Heap::kNoGCFlags,
71 0 : GarbageCollectionReason::kCountersExtension);
72 : }
73 : }
74 :
75 : Counters* counters = isolate->counters();
76 0 : v8::Local<v8::Object> result = v8::Object::New(args.GetIsolate());
77 :
78 : struct StatisticsCounter {
79 : v8::internal::StatsCounter* counter;
80 : const char* name;
81 : };
82 : const StatisticsCounter counter_list[] = {
83 : #define ADD_COUNTER(name, caption) \
84 : { counters->name(), #name } \
85 : ,
86 :
87 0 : STATS_COUNTER_LIST_1(ADD_COUNTER) STATS_COUNTER_LIST_2(ADD_COUNTER)
88 : #undef ADD_COUNTER
89 : #define ADD_COUNTER(name) \
90 : { counters->count_of_##name(), "count_of_" #name } \
91 : , {counters->size_of_##name(), "size_of_" #name},
92 :
93 0 : INSTANCE_TYPE_LIST(ADD_COUNTER)
94 : #undef ADD_COUNTER
95 : #define ADD_COUNTER(name) \
96 : { counters->count_of_CODE_TYPE_##name(), "count_of_CODE_TYPE_" #name } \
97 : , {counters->size_of_CODE_TYPE_##name(), "size_of_CODE_TYPE_" #name},
98 :
99 0 : CODE_KIND_LIST(ADD_COUNTER)
100 : #undef ADD_COUNTER
101 : #define ADD_COUNTER(name) \
102 : { counters->count_of_FIXED_ARRAY_##name(), "count_of_FIXED_ARRAY_" #name } \
103 : , {counters->size_of_FIXED_ARRAY_##name(), "size_of_FIXED_ARRAY_" #name},
104 :
105 0 : FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADD_COUNTER)
106 : #undef ADD_COUNTER
107 0 : }; // End counter_list array.
108 :
109 0 : for (size_t i = 0; i < arraysize(counter_list); i++) {
110 : AddCounter(args.GetIsolate(), result, counter_list[i].counter,
111 0 : counter_list[i].name);
112 : }
113 :
114 : struct StatisticNumber {
115 : size_t number;
116 : const char* name;
117 : };
118 :
119 : const StatisticNumber numbers[] = {
120 : {heap->memory_allocator()->Size(), "total_committed_bytes"},
121 0 : {heap->new_space()->Size(), "new_space_live_bytes"},
122 0 : {heap->new_space()->Available(), "new_space_available_bytes"},
123 0 : {heap->new_space()->CommittedMemory(), "new_space_commited_bytes"},
124 0 : {heap->old_space()->Size(), "old_space_live_bytes"},
125 0 : {heap->old_space()->Available(), "old_space_available_bytes"},
126 0 : {heap->old_space()->CommittedMemory(), "old_space_commited_bytes"},
127 0 : {heap->code_space()->Size(), "code_space_live_bytes"},
128 0 : {heap->code_space()->Available(), "code_space_available_bytes"},
129 0 : {heap->code_space()->CommittedMemory(), "code_space_commited_bytes"},
130 0 : {heap->lo_space()->Size(), "lo_space_live_bytes"},
131 0 : {heap->lo_space()->Available(), "lo_space_available_bytes"},
132 0 : {heap->lo_space()->CommittedMemory(), "lo_space_commited_bytes"},
133 0 : };
134 :
135 0 : for (size_t i = 0; i < arraysize(numbers); i++) {
136 0 : AddNumber(args.GetIsolate(), result, numbers[i].number, numbers[i].name);
137 : }
138 :
139 : AddNumber64(args.GetIsolate(), result, heap->external_memory(),
140 0 : "amount_of_external_allocated_memory");
141 : args.GetReturnValue().Set(result);
142 :
143 0 : HeapIterator iterator(reinterpret_cast<Isolate*>(args.GetIsolate())->heap());
144 : HeapObject* obj;
145 : int reloc_info_total = 0;
146 : int source_position_table_total = 0;
147 0 : while ((obj = iterator.next()) != nullptr) {
148 0 : if (obj->IsCode()) {
149 : Code* code = Code::cast(obj);
150 0 : reloc_info_total += code->relocation_info()->Size();
151 0 : ByteArray* source_position_table = code->SourcePositionTable();
152 0 : if (source_position_table->length() > 0) {
153 0 : source_position_table_total += code->SourcePositionTable()->Size();
154 : }
155 0 : } else if (obj->IsBytecodeArray()) {
156 : source_position_table_total +=
157 0 : BytecodeArray::cast(obj)->SourcePositionTable()->Size();
158 : }
159 : }
160 :
161 : AddNumber(args.GetIsolate(), result, reloc_info_total,
162 0 : "reloc_info_total_size");
163 : AddNumber(args.GetIsolate(), result, source_position_table_total,
164 0 : "source_position_table_total_size");
165 0 : }
166 :
167 : } // namespace internal
168 : } // namespace v8
|