• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #include "node.h"
23 #include "env-inl.h"
24 #include "util-inl.h"
25 #include "v8.h"
26 
27 namespace node {
28 
29 using v8::Array;
30 using v8::ArrayBuffer;
31 using v8::Context;
32 using v8::FunctionCallbackInfo;
33 using v8::HeapCodeStatistics;
34 using v8::HeapSpaceStatistics;
35 using v8::HeapStatistics;
36 using v8::Integer;
37 using v8::Isolate;
38 using v8::Local;
39 using v8::NewStringType;
40 using v8::Object;
41 using v8::ScriptCompiler;
42 using v8::String;
43 using v8::Uint32;
44 using v8::V8;
45 using v8::Value;
46 
47 
48 #define HEAP_STATISTICS_PROPERTIES(V)                                         \
49   V(0, total_heap_size, kTotalHeapSizeIndex)                                  \
50   V(1, total_heap_size_executable, kTotalHeapSizeExecutableIndex)             \
51   V(2, total_physical_size, kTotalPhysicalSizeIndex)                          \
52   V(3, total_available_size, kTotalAvailableSize)                             \
53   V(4, used_heap_size, kUsedHeapSizeIndex)                                    \
54   V(5, heap_size_limit, kHeapSizeLimitIndex)                                  \
55   V(6, malloced_memory, kMallocedMemoryIndex)                                 \
56   V(7, peak_malloced_memory, kPeakMallocedMemoryIndex)                        \
57   V(8, does_zap_garbage, kDoesZapGarbageIndex)                                \
58   V(9, number_of_native_contexts, kNumberOfNativeContextsIndex)               \
59   V(10, number_of_detached_contexts, kNumberOfDetachedContextsIndex)
60 
61 #define V(a, b, c) +1
62 static const size_t kHeapStatisticsPropertiesCount =
63     HEAP_STATISTICS_PROPERTIES(V);
64 #undef V
65 
66 
67 #define HEAP_SPACE_STATISTICS_PROPERTIES(V)                                   \
68   V(0, space_size, kSpaceSizeIndex)                                           \
69   V(1, space_used_size, kSpaceUsedSizeIndex)                                  \
70   V(2, space_available_size, kSpaceAvailableSizeIndex)                        \
71   V(3, physical_space_size, kPhysicalSpaceSizeIndex)
72 
73 #define V(a, b, c) +1
74 static const size_t kHeapSpaceStatisticsPropertiesCount =
75     HEAP_SPACE_STATISTICS_PROPERTIES(V);
76 #undef V
77 
78 
79 #define HEAP_CODE_STATISTICS_PROPERTIES(V)                                    \
80   V(0, code_and_metadata_size, kCodeAndMetadataSizeIndex)                    \
81   V(1, bytecode_and_metadata_size, kBytecodeAndMetadataSizeIndex)             \
82   V(2, external_script_source_size, kExternalScriptSourceSizeIndex)
83 
84 #define V(a, b, c) +1
85 static const size_t kHeapCodeStatisticsPropertiesCount =
86     HEAP_CODE_STATISTICS_PROPERTIES(V);
87 #undef V
88 
CachedDataVersionTag(const FunctionCallbackInfo<Value> & args)89 void CachedDataVersionTag(const FunctionCallbackInfo<Value>& args) {
90   Environment* env = Environment::GetCurrent(args);
91   Local<Integer> result =
92       Integer::NewFromUnsigned(env->isolate(),
93                                ScriptCompiler::CachedDataVersionTag());
94   args.GetReturnValue().Set(result);
95 }
96 
97 
UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo<Value> & args)98 void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo<Value>& args) {
99   Environment* env = Environment::GetCurrent(args);
100   HeapStatistics s;
101   env->isolate()->GetHeapStatistics(&s);
102   double* const buffer = env->heap_statistics_buffer();
103 #define V(index, name, _) buffer[index] = static_cast<double>(s.name());
104   HEAP_STATISTICS_PROPERTIES(V)
105 #undef V
106 }
107 
108 
UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo<Value> & args)109 void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo<Value>& args) {
110   Environment* env = Environment::GetCurrent(args);
111   HeapSpaceStatistics s;
112   Isolate* const isolate = env->isolate();
113   double* buffer = env->heap_space_statistics_buffer();
114   size_t number_of_heap_spaces = env->isolate()->NumberOfHeapSpaces();
115 
116   for (size_t i = 0; i < number_of_heap_spaces; i++) {
117     isolate->GetHeapSpaceStatistics(&s, i);
118     size_t const property_offset = i * kHeapSpaceStatisticsPropertiesCount;
119 #define V(index, name, _) buffer[property_offset + index] = \
120                               static_cast<double>(s.name());
121       HEAP_SPACE_STATISTICS_PROPERTIES(V)
122 #undef V
123   }
124 }
125 
126 
UpdateHeapCodeStatisticsArrayBuffer(const FunctionCallbackInfo<Value> & args)127 void UpdateHeapCodeStatisticsArrayBuffer(
128     const FunctionCallbackInfo<Value>& args) {
129   Environment* env = Environment::GetCurrent(args);
130   HeapCodeStatistics s;
131   env->isolate()->GetHeapCodeAndMetadataStatistics(&s);
132   double* const buffer = env->heap_code_statistics_buffer();
133 #define V(index, name, _) buffer[index] = static_cast<double>(s.name());
134   HEAP_CODE_STATISTICS_PROPERTIES(V)
135 #undef V
136 }
137 
138 
SetFlagsFromString(const FunctionCallbackInfo<Value> & args)139 void SetFlagsFromString(const FunctionCallbackInfo<Value>& args) {
140   CHECK(args[0]->IsString());
141   String::Utf8Value flags(args.GetIsolate(), args[0]);
142   V8::SetFlagsFromString(*flags, flags.length());
143 }
144 
145 
Initialize(Local<Object> target,Local<Value> unused,Local<Context> context,void * priv)146 void Initialize(Local<Object> target,
147                 Local<Value> unused,
148                 Local<Context> context,
149                 void* priv) {
150   Environment* env = Environment::GetCurrent(context);
151 
152   env->SetMethodNoSideEffect(target, "cachedDataVersionTag",
153                              CachedDataVersionTag);
154 
155   // Export symbols used by v8.getHeapStatistics()
156   env->SetMethod(target,
157                  "updateHeapStatisticsArrayBuffer",
158                  UpdateHeapStatisticsArrayBuffer);
159 
160   env->set_heap_statistics_buffer(new double[kHeapStatisticsPropertiesCount]);
161 
162   const size_t heap_statistics_buffer_byte_length =
163       sizeof(*env->heap_statistics_buffer()) * kHeapStatisticsPropertiesCount;
164 
165   target->Set(env->context(),
166               FIXED_ONE_BYTE_STRING(env->isolate(),
167                                     "heapStatisticsArrayBuffer"),
168               ArrayBuffer::New(env->isolate(),
169                                env->heap_statistics_buffer(),
170                                heap_statistics_buffer_byte_length)).Check();
171 
172 #define V(i, _, name)                                                         \
173   target->Set(env->context(),                                                 \
174               FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
175               Uint32::NewFromUnsigned(env->isolate(), i)).Check();
176 
177   HEAP_STATISTICS_PROPERTIES(V)
178 #undef V
179 
180   // Export symbols used by v8.getHeapCodeStatistics()
181   env->SetMethod(target,
182                  "updateHeapCodeStatisticsArrayBuffer",
183                  UpdateHeapCodeStatisticsArrayBuffer);
184 
185   env->set_heap_code_statistics_buffer(
186     new double[kHeapCodeStatisticsPropertiesCount]);
187 
188   const size_t heap_code_statistics_buffer_byte_length =
189       sizeof(*env->heap_code_statistics_buffer())
190       * kHeapCodeStatisticsPropertiesCount;
191 
192   target->Set(env->context(),
193               FIXED_ONE_BYTE_STRING(env->isolate(),
194                                     "heapCodeStatisticsArrayBuffer"),
195               ArrayBuffer::New(env->isolate(),
196                                env->heap_code_statistics_buffer(),
197                                heap_code_statistics_buffer_byte_length))
198   .Check();
199 
200 #define V(i, _, name)                                                         \
201   target->Set(env->context(),                                                 \
202               FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
203               Uint32::NewFromUnsigned(env->isolate(), i)).Check();
204 
205   HEAP_CODE_STATISTICS_PROPERTIES(V)
206 #undef V
207 
208   // Export symbols used by v8.getHeapSpaceStatistics()
209   target->Set(env->context(),
210               FIXED_ONE_BYTE_STRING(env->isolate(),
211                                     "kHeapSpaceStatisticsPropertiesCount"),
212               Uint32::NewFromUnsigned(env->isolate(),
213                                       kHeapSpaceStatisticsPropertiesCount))
214               .Check();
215 
216   size_t number_of_heap_spaces = env->isolate()->NumberOfHeapSpaces();
217 
218   // Heap space names are extracted once and exposed to JavaScript to
219   // avoid excessive creation of heap space name Strings.
220   HeapSpaceStatistics s;
221   MaybeStackBuffer<Local<Value>, 16> heap_spaces(number_of_heap_spaces);
222   for (size_t i = 0; i < number_of_heap_spaces; i++) {
223     env->isolate()->GetHeapSpaceStatistics(&s, i);
224     heap_spaces[i] = String::NewFromUtf8(env->isolate(),
225                                          s.space_name(),
226                                          NewStringType::kNormal)
227                                              .ToLocalChecked();
228   }
229   target->Set(env->context(),
230               FIXED_ONE_BYTE_STRING(env->isolate(), "kHeapSpaces"),
231               Array::New(env->isolate(),
232                          heap_spaces.out(),
233                          number_of_heap_spaces)).Check();
234 
235   env->SetMethod(target,
236                  "updateHeapSpaceStatisticsArrayBuffer",
237                  UpdateHeapSpaceStatisticsBuffer);
238 
239   env->set_heap_space_statistics_buffer(
240     new double[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]);
241 
242   const size_t heap_space_statistics_buffer_byte_length =
243       sizeof(*env->heap_space_statistics_buffer()) *
244       kHeapSpaceStatisticsPropertiesCount *
245       number_of_heap_spaces;
246 
247   target->Set(env->context(),
248               FIXED_ONE_BYTE_STRING(env->isolate(),
249                                     "heapSpaceStatisticsArrayBuffer"),
250               ArrayBuffer::New(env->isolate(),
251                                env->heap_space_statistics_buffer(),
252                                heap_space_statistics_buffer_byte_length))
253               .Check();
254 
255 #define V(i, _, name)                                                         \
256   target->Set(env->context(),                                                 \
257               FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
258               Uint32::NewFromUnsigned(env->isolate(), i)).Check();
259 
260   HEAP_SPACE_STATISTICS_PROPERTIES(V)
261 #undef V
262 
263   // Export symbols used by v8.setFlagsFromString()
264   env->SetMethod(target, "setFlagsFromString", SetFlagsFromString);
265 }
266 
267 }  // namespace node
268 
269 NODE_MODULE_CONTEXT_AWARE_INTERNAL(v8, node::Initialize)
270