| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,9 +17,8 @@ using v8::Integer; | |||
| 17 | 17 | using v8::Isolate; | |
| 18 | 18 | using v8::Local; | |
| 19 | 19 | using v8::Name; | |
| 20 | + using v8::Number; | ||
| 20 | 21 | using v8::Object; | |
| 21 | - using v8::ObjectTemplate; | ||
| 22 | - using v8::Signature; | ||
| 23 | 22 | using v8::String; | |
| 24 | 23 | using v8::Value; | |
| 25 | 24 | ||
@@ -30,63 +29,107 @@ uint64_t performance_v8_start; | |||
| 30 | 29 | uint64_t performance_last_gc_start_mark_ = 0; | |
| 31 | 30 | v8::GCType performance_last_gc_type_ = v8::GCType::kGCTypeAll; | |
| 32 | 31 | ||
| 32 | + // Initialize the performance entry object properties | ||
| 33 | + inline void InitObject(const PerformanceEntry& entry, Local<Object> obj) { | ||
| 34 | + Environment* env = entry.env(); | ||
| 35 | + Isolate* isolate = env->isolate(); | ||
| 36 | + Local<Context> context = env->context(); | ||
| 37 | + v8::PropertyAttribute attr = | ||
| 38 | + static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); | ||
| 39 | + obj->DefineOwnProperty(context, | ||
| 40 | + env->name_string(), | ||
| 41 | + String::NewFromUtf8(isolate, | ||
| 42 | + entry.name().c_str(), | ||
| 43 | + String::kNormalString), | ||
| 44 | + attr).FromJust(); | ||
| 45 | + obj->DefineOwnProperty(context, | ||
| 46 | + FIXED_ONE_BYTE_STRING(isolate, "entryType"), | ||
| 47 | + String::NewFromUtf8(isolate, | ||
| 48 | + entry.type().c_str(), | ||
| 49 | + String::kNormalString), | ||
| 50 | + attr).FromJust(); | ||
| 51 | + obj->DefineOwnProperty(context, | ||
| 52 | + FIXED_ONE_BYTE_STRING(isolate, "startTime"), | ||
| 53 | + Number::New(isolate, entry.startTime()), | ||
| 54 | + attr).FromJust(); | ||
| 55 | + obj->DefineOwnProperty(context, | ||
| 56 | + FIXED_ONE_BYTE_STRING(isolate, "duration"), | ||
| 57 | + Number::New(isolate, entry.duration()), | ||
| 58 | + attr).FromJust(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + // Create a new PerformanceEntry object | ||
| 62 | + const Local<Object> PerformanceEntry::ToObject() const { | ||
| 63 | + Local<Object> obj = | ||
| 64 | + env_->performance_entry_template() | ||
| 65 | + ->NewInstance(env_->context()).ToLocalChecked(); | ||
| 66 | + InitObject(*this, obj); | ||
| 67 | + return obj; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + // Allow creating a PerformanceEntry object from JavaScript | ||
| 33 | 71 | void PerformanceEntry::New(const FunctionCallbackInfo<Value>& args) { | |
| 34 | 72 | Environment* env = Environment::GetCurrent(args); | |
| 35 | 73 | Isolate* isolate = env->isolate(); | |
| 36 | 74 | Utf8Value name(isolate, args[0]); | |
| 37 | 75 | Utf8Value type(isolate, args[1]); | |
| 38 | 76 | uint64_t now = PERFORMANCE_NOW(); | |
| 39 | - new PerformanceEntry(env, args.This(), *name, *type, now, now); | ||
| 77 | + PerformanceEntry entry(env, *name, *type, now, now); | ||
| 78 | + Local<Object> obj = args.This(); | ||
| 79 | + InitObject(entry, obj); | ||
| 80 | + PerformanceEntry::Notify(env, entry.kind(), obj); | ||
| 40 | 81 | } | |
| 41 | 82 | ||
| 42 | - void PerformanceEntry::NotifyObservers(Environment* env, | ||
| 43 | - PerformanceEntry* entry) { | ||
| 83 | + // Pass the PerformanceEntry object to the PerformanceObservers | ||
| 84 | + inline void PerformanceEntry::Notify(Environment* env, | ||
| 85 | + PerformanceEntryType type, | ||
| 86 | + Local<Value> object) { | ||
| 87 | + Context::Scope scope(env->context()); | ||
| 44 | 88 | AliasedBuffer<uint32_t, v8::Uint32Array>& observers = | |
| 45 | 89 | env->performance_state()->observers; | |
| 46 | - PerformanceEntryType type = ToPerformanceEntryTypeEnum(entry->type().c_str()); | ||
| 47 | - if (type == NODE_PERFORMANCE_ENTRY_TYPE_INVALID || | ||
| 48 | - !observers[type]) { | ||
| 49 | - return; | ||
| 90 | + if (observers != nullptr && | ||
| 91 | + type != NODE_PERFORMANCE_ENTRY_TYPE_INVALID && | ||
| 92 | + observers[type]) { | ||
| 93 | + node::MakeCallback(env->isolate(), | ||
| 94 | + env->process_object(), | ||
| 95 | + env->performance_entry_callback(), | ||
| 96 | + 1, &object); | ||
| 50 | 97 | } | |
| 51 | - Local<Context> context = env->context(); | ||
| 52 | - Isolate* isolate = env->isolate(); | ||
| 53 | - Local<Value> argv = entry->object(); | ||
| 54 | - env->performance_entry_callback()->Call(context, | ||
| 55 | - v8::Undefined(isolate), | ||
| 56 | - 1, &argv).ToLocalChecked(); | ||
| 57 | 98 | } | |
| 58 | 99 | ||
| 100 | + // Create a User Timing Mark | ||
| 59 | 101 | void Mark(const FunctionCallbackInfo<Value>& args) { | |
| 60 | 102 | Environment* env = Environment::GetCurrent(args); | |
| 61 | - Local<Context> context = env->context(); | ||
| 62 | - Isolate* isolate = env->isolate(); | ||
| 63 | - Utf8Value name(isolate, args[0]); | ||
| 103 | + HandleScope scope(env->isolate()); | ||
| 104 | + Utf8Value name(env->isolate(), args[0]); | ||
| 64 | 105 | uint64_t now = PERFORMANCE_NOW(); | |
| 65 | 106 | auto marks = env->performance_marks(); | |
| 66 | 107 | (*marks)[*name] = now; | |
| 67 | 108 | ||
| 68 | 109 | // TODO(jasnell): Once Tracing API is fully implemented, this should | |
| 69 | 110 | // record a trace event also. | |
| 70 | 111 | ||
| 71 | - Local<Function> fn = env->performance_entry_template(); | ||
| 72 | - Local<Object> obj = fn->NewInstance(context).ToLocalChecked(); | ||
| 73 | - new PerformanceEntry(env, obj, *name, "mark", now, now); | ||
| 112 | + PerformanceEntry entry(env, *name, "mark", now, now); | ||
| 113 | + Local<Object> obj = entry.ToObject(); | ||
| 114 | + PerformanceEntry::Notify(env, entry.kind(), obj); | ||
| 74 | 115 | args.GetReturnValue().Set(obj); | |
| 75 | 116 | } | |
| 76 | 117 | ||
| 118 | + | ||
| 77 | 119 | inline uint64_t GetPerformanceMark(Environment* env, std::string name) { | |
| 78 | 120 | auto marks = env->performance_marks(); | |
| 79 | 121 | auto res = marks->find(name); | |
| 80 | 122 | return res != marks->end() ? res->second : 0; | |
| 81 | 123 | } | |
| 82 | 124 | ||
| 125 | + // Create a User Timing Measure. A Measure is a PerformanceEntry that | ||
| 126 | + // measures the duration between two distinct user timing marks | ||
| 83 | 127 | void Measure(const FunctionCallbackInfo<Value>& args) { | |
| 84 | 128 | Environment* env = Environment::GetCurrent(args); | |
| 85 | - Local<Context> context = env->context(); | ||
| 86 | - Isolate* isolate = env->isolate(); | ||
| 87 | - Utf8Value name(isolate, args[0]); | ||
| 88 | - Utf8Value startMark(isolate, args[1]); | ||
| 89 | - Utf8Value endMark(isolate, args[2]); | ||
| 129 | + HandleScope scope(env->isolate()); | ||
| 130 | + Utf8Value name(env->isolate(), args[0]); | ||
| 131 | + Utf8Value startMark(env->isolate(), args[1]); | ||
| 132 | + Utf8Value endMark(env->isolate(), args[2]); | ||
| 90 | 133 | ||
| 91 | 134 | AliasedBuffer<double, v8::Float64Array>& milestones = | |
| 92 | 135 | env->performance_state()->milestones; | |
@@ -114,41 +157,13 @@ void Measure(const FunctionCallbackInfo<Value>& args) { | |||
| 114 | 157 | // TODO(jasnell): Once Tracing API is fully implemented, this should | |
| 115 | 158 | // record a trace event also. | |
| 116 | 159 | ||
| 117 | - Local<Function> fn = env->performance_entry_template(); | ||
| 118 | - Local<Object> obj = fn->NewInstance(context).ToLocalChecked(); | ||
| 119 | - new PerformanceEntry(env, obj, *name, "measure", | ||
| 120 | - startTimestamp, endTimestamp); | ||
| 160 | + PerformanceEntry entry(env, *name, "measure", startTimestamp, endTimestamp); | ||
| 161 | + Local<Object> obj = entry.ToObject(); | ||
| 162 | + PerformanceEntry::Notify(env, entry.kind(), obj); | ||
| 121 | 163 | args.GetReturnValue().Set(obj); | |
| 122 | 164 | } | |
| 123 | 165 | ||
| 124 | - void GetPerformanceEntryName(const FunctionCallbackInfo<Value>& info) { | ||
| 125 | - Isolate* isolate = info.GetIsolate(); | ||
| 126 | - PerformanceEntry* entry; | ||
| 127 | - ASSIGN_OR_RETURN_UNWRAP(&entry, info.Holder()); | ||
| 128 | - info.GetReturnValue().Set( | ||
| 129 | - String::NewFromUtf8(isolate, entry->name().c_str(), String::kNormalString)); | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - void GetPerformanceEntryType(const FunctionCallbackInfo<Value>& info) { | ||
| 133 | - Isolate* isolate = info.GetIsolate(); | ||
| 134 | - PerformanceEntry* entry; | ||
| 135 | - ASSIGN_OR_RETURN_UNWRAP(&entry, info.Holder()); | ||
| 136 | - info.GetReturnValue().Set( | ||
| 137 | - String::NewFromUtf8(isolate, entry->type().c_str(), String::kNormalString)); | ||
| 138 | - } | ||
| 139 | - | ||
| 140 | - void GetPerformanceEntryStartTime(const FunctionCallbackInfo<Value>& info) { | ||
| 141 | - PerformanceEntry* entry; | ||
| 142 | - ASSIGN_OR_RETURN_UNWRAP(&entry, info.Holder()); | ||
| 143 | - info.GetReturnValue().Set(entry->startTime()); | ||
| 144 | - } | ||
| 145 | - | ||
| 146 | - void GetPerformanceEntryDuration(const FunctionCallbackInfo<Value>& info) { | ||
| 147 | - PerformanceEntry* entry; | ||
| 148 | - ASSIGN_OR_RETURN_UNWRAP(&entry, info.Holder()); | ||
| 149 | - info.GetReturnValue().Set(entry->duration()); | ||
| 150 | - } | ||
| 151 | - | ||
| 166 | + // Allows specific Node.js lifecycle milestones to be set from JavaScript | ||
| 152 | 167 | void MarkMilestone(const FunctionCallbackInfo<Value>& args) { | |
| 153 | 168 | Environment* env = Environment::GetCurrent(args); | |
| 154 | 169 | Local<Context> context = env->context(); | |
@@ -162,74 +177,64 @@ void MarkMilestone(const FunctionCallbackInfo<Value>& args) { | |||
| 162 | 177 | } | |
| 163 | 178 | } | |
| 164 | 179 | ||
| 180 | + | ||
| 165 | 181 | void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) { | |
| 166 | 182 | Environment* env = Environment::GetCurrent(args); | |
| 167 | 183 | CHECK(args[0]->IsFunction()); | |
| 168 | 184 | env->set_performance_entry_callback(args[0].As<Function>()); | |
| 169 | 185 | } | |
| 170 | 186 | ||
| 171 | - void PerformanceGCCallback(uv_async_t* handle) { | ||
| 172 | - PerformanceEntry::Data* data = | ||
| 173 | - static_cast<PerformanceEntry::Data*>(handle->data); | ||
| 174 | - Environment* env = data->env(); | ||
| 175 | - Isolate* isolate = env->isolate(); | ||
| 176 | - HandleScope scope(isolate); | ||
| 187 | + // Creates a GC Performance Entry and passes it to observers | ||
| 188 | + void PerformanceGCCallback(Environment* env, void* ptr) { | ||
| 189 | + GCPerformanceEntry* entry = static_cast<GCPerformanceEntry*>(ptr); | ||
| 190 | + HandleScope scope(env->isolate()); | ||
| 177 | 191 | Local<Context> context = env->context(); | |
| 178 | - Context::Scope context_scope(context); | ||
| 179 | - Local<Function> fn; | ||
| 180 | - Local<Object> obj; | ||
| 181 | - PerformanceGCKind kind = static_cast<PerformanceGCKind>(data->data()); | ||
| 182 | 192 | ||
| 183 | 193 | AliasedBuffer<uint32_t, v8::Uint32Array>& observers = | |
| 184 | 194 | env->performance_state()->observers; | |
| 185 | - if (!observers[NODE_PERFORMANCE_ENTRY_TYPE_GC]) { | ||
| 186 | - goto cleanup; | ||
| 195 | + if (observers[NODE_PERFORMANCE_ENTRY_TYPE_GC]) { | ||
| 196 | + Local<Object> obj = entry->ToObject(); | ||
| 197 | + v8::PropertyAttribute attr = | ||
| 198 | + static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); | ||
| 199 | + obj->DefineOwnProperty(context, | ||
| 200 | + FIXED_ONE_BYTE_STRING(env->isolate(), "kind"), | ||
| 201 | + Integer::New(env->isolate(), entry->gckind()), | ||
| 202 | + attr).FromJust(); | ||
| 203 | + PerformanceEntry::Notify(env, entry->kind(), obj); | ||
| 187 | 204 | } | |
| 188 | 205 | ||
| 189 | - fn = env->performance_entry_template(); | ||
| 190 | - obj = fn->NewInstance(context).ToLocalChecked(); | ||
| 191 | - obj->Set(context, | ||
| 192 | - FIXED_ONE_BYTE_STRING(isolate, "kind"), | ||
| 193 | - Integer::New(isolate, kind)).FromJust(); | ||
| 194 | - new PerformanceEntry(env, obj, data); | ||
| 195 | - | ||
| 196 | - cleanup: | ||
| 197 | - delete data; | ||
| 198 | - auto closeCB = [](uv_handle_t* handle) { | ||
| 199 | - delete reinterpret_cast<uv_async_t*>(handle); | ||
| 200 | - }; | ||
| 201 | - uv_close(reinterpret_cast<uv_handle_t*>(handle), closeCB); | ||
| 206 | + delete entry; | ||
| 202 | 207 | } | |
| 203 | 208 | ||
| 209 | + // Marks the start of a GC cycle | ||
| 204 | 210 | void MarkGarbageCollectionStart(Isolate* isolate, | |
| 205 | 211 | v8::GCType type, | |
| 206 | 212 | v8::GCCallbackFlags flags) { | |
| 207 | 213 | performance_last_gc_start_mark_ = PERFORMANCE_NOW(); | |
| 208 | 214 | performance_last_gc_type_ = type; | |
| 209 | 215 | } | |
| 210 | 216 | ||
| 217 | + // Marks the end of a GC cycle | ||
| 211 | 218 | void MarkGarbageCollectionEnd(Isolate* isolate, | |
| 212 | 219 | v8::GCType type, | |
| 213 | 220 | v8::GCCallbackFlags flags, | |
| 214 | 221 | void* data) { | |
| 215 | 222 | Environment* env = static_cast<Environment*>(data); | |
| 216 | - uv_async_t* async = new uv_async_t(); // coverity[leaked_storage] | ||
| 217 | - if (uv_async_init(env->event_loop(), async, PerformanceGCCallback)) | ||
| 218 | - return delete async; | ||
| 219 | - uv_unref(reinterpret_cast<uv_handle_t*>(async)); | ||
| 220 | - async->data = | ||
| 221 | - new PerformanceEntry::Data(env, "gc", "gc", | ||
| 222 | - performance_last_gc_start_mark_, | ||
| 223 | - PERFORMANCE_NOW(), type); | ||
| 224 | - CHECK_EQ(0, uv_async_send(async)); | ||
| 223 | + env->SetImmediate(PerformanceGCCallback, | ||
| 224 | + new GCPerformanceEntry(env, | ||
| 225 | + static_cast<PerformanceGCKind>(type), | ||
| 226 | + performance_last_gc_start_mark_, | ||
| 227 | + PERFORMANCE_NOW())); | ||
| 225 | 228 | } | |
| 226 | 229 | ||
| 230 | + | ||
| 227 | 231 | inline void SetupGarbageCollectionTracking(Environment* env) { | |
| 228 | 232 | env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart); | |
| 229 | 233 | env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd, | |
| 230 | 234 | static_cast<void*>(env)); | |
| 231 | 235 | } | |
| 232 | 236 | ||
| 237 | + // Gets the name of a function | ||
| 233 | 238 | inline Local<Value> GetName(Local<Function> fn) { | |
| 234 | 239 | Local<Value> val = fn->GetDebugName(); | |
| 235 | 240 | if (val.IsEmpty() || val->IsUndefined()) { | |
@@ -241,6 +246,9 @@ inline Local<Value> GetName(Local<Function> fn) { | |||
| 241 | 246 | return val; | |
| 242 | 247 | } | |
| 243 | 248 | ||
| 249 | + // Executes a wrapped Function and captures timing information, causing a | ||
| 250 | + // Function PerformanceEntry to be emitted to PerformanceObservers after | ||
| 251 | + // execution. | ||
| 244 | 252 | void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) { | |
| 245 | 253 | Isolate* isolate = args.GetIsolate(); | |
| 246 | 254 | HandleScope scope(isolate); | |
@@ -250,9 +258,8 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) { | |||
| 250 | 258 | size_t count = args.Length(); | |
| 251 | 259 | size_t idx; | |
| 252 | 260 | std::vector<Local<Value>> call_args; | |
| 253 | - for (size_t i = 0; i < count; ++i) { | ||
| 261 | + for (size_t i = 0; i < count; ++i) | ||
| 254 | 262 | call_args.push_back(args[i]); | |
| 255 | - } | ||
| 256 | 263 | ||
| 257 | 264 | Utf8Value name(isolate, GetName(fn)); | |
| 258 | 265 | ||
@@ -289,15 +296,14 @@ void TimerFunctionCall(const FunctionCallbackInfo<Value>& args) { | |||
| 289 | 296 | if (!observers[NODE_PERFORMANCE_ENTRY_TYPE_FUNCTION]) | |
| 290 | 297 | return; | |
| 291 | 298 | ||
| 292 | - Local<Function> ctor = env->performance_entry_template(); | ||
| 293 | - v8::MaybeLocal<Object> instance = ctor->NewInstance(context); | ||
| 294 | - Local<Object> obj = instance.ToLocalChecked(); | ||
| 295 | - for (idx = 0; idx < count; idx++) { | ||
| 296 | - obj->Set(context, idx, args[idx]).ToChecked(); | ||
| 297 | - } | ||
| 298 | - new PerformanceEntry(env, obj, *name, "function", start, end); | ||
| 299 | + PerformanceEntry entry(env, *name, "function", start, end); | ||
| 300 | + Local<Object> obj = entry.ToObject(); | ||
| 301 | + for (idx = 0; idx < count; idx++) | ||
| 302 | + obj->Set(context, idx, args[idx]).FromJust(); | ||
| 303 | + PerformanceEntry::Notify(env, entry.kind(), obj); | ||
| 299 | 304 | } | |
| 300 | 305 | ||
| 306 | + // Wraps a Function in a TimerFunctionCall | ||
| 301 | 307 | void Timerify(const FunctionCallbackInfo<Value>& args) { | |
| 302 | 308 | Environment* env = Environment::GetCurrent(args); | |
| 303 | 309 | Local<Context> context = env->context(); | |
@@ -310,6 +316,7 @@ void Timerify(const FunctionCallbackInfo<Value>& args) { | |||
| 310 | 316 | args.GetReturnValue().Set(wrap); | |
| 311 | 317 | } | |
| 312 | 318 | ||
| 319 | + | ||
| 313 | 320 | void Init(Local<Object> target, | |
| 314 | 321 | Local<Value> unused, | |
| 315 | 322 | Local<Context> context) { | |
@@ -328,55 +335,10 @@ void Init(Local<Object> target, | |||
| 328 | 335 | Local<String> performanceEntryString = | |
| 329 | 336 | FIXED_ONE_BYTE_STRING(isolate, "PerformanceEntry"); | |
| 330 | 337 | ||
| 331 | - Local<FunctionTemplate> pe = env->NewFunctionTemplate(PerformanceEntry::New); | ||
| 332 | - pe->InstanceTemplate()->SetInternalFieldCount(1); | ||
| 338 | + Local<FunctionTemplate> pe = FunctionTemplate::New(isolate); | ||
| 333 | 339 | pe->SetClassName(performanceEntryString); | |
| 334 | - | ||
| 335 | - Local<Signature> signature = Signature::New(env->isolate(), pe); | ||
| 336 | - | ||
| 337 | - Local<FunctionTemplate> get_performance_entry_name_templ = | ||
| 338 | - FunctionTemplate::New(env->isolate(), | ||
| 339 | - GetPerformanceEntryName, | ||
| 340 | - env->as_external(), | ||
| 341 | - signature); | ||
| 342 | - | ||
| 343 | - Local<FunctionTemplate> get_performance_entry_type_templ = | ||
| 344 | - FunctionTemplate::New(env->isolate(), | ||
| 345 | - GetPerformanceEntryType, | ||
| 346 | - env->as_external(), | ||
| 347 | - signature); | ||
| 348 | - | ||
| 349 | - Local<FunctionTemplate> get_performance_entry_start_time_templ = | ||
| 350 | - FunctionTemplate::New(env->isolate(), | ||
| 351 | - GetPerformanceEntryStartTime, | ||
| 352 | - env->as_external(), | ||
| 353 | - signature); | ||
| 354 | - | ||
| 355 | - Local<FunctionTemplate> get_performance_entry_duration_templ = | ||
| 356 | - FunctionTemplate::New(env->isolate(), | ||
| 357 | - GetPerformanceEntryDuration, | ||
| 358 | - env->as_external(), | ||
| 359 | - signature); | ||
| 360 | - | ||
| 361 | - Local<ObjectTemplate> ot = pe->InstanceTemplate(); | ||
| 362 | - ot->SetAccessorProperty(env->name_string(), | ||
| 363 | - get_performance_entry_name_templ, | ||
| 364 | - Local<FunctionTemplate>()); | ||
| 365 | - | ||
| 366 | - ot->SetAccessorProperty(FIXED_ONE_BYTE_STRING(isolate, "entryType"), | ||
| 367 | - get_performance_entry_type_templ, | ||
| 368 | - Local<FunctionTemplate>()); | ||
| 369 | - | ||
| 370 | - ot->SetAccessorProperty(FIXED_ONE_BYTE_STRING(isolate, "startTime"), | ||
| 371 | - get_performance_entry_start_time_templ, | ||
| 372 | - Local<FunctionTemplate>()); | ||
| 373 | - | ||
| 374 | - ot->SetAccessorProperty(FIXED_ONE_BYTE_STRING(isolate, "duration"), | ||
| 375 | - get_performance_entry_duration_templ, | ||
| 376 | - Local<FunctionTemplate>()); | ||
| 377 | - | ||
| 378 | 340 | Local<Function> fn = pe->GetFunction(); | |
| 379 | - target->Set(performanceEntryString, fn); | ||
| 341 | + target->Set(context, performanceEntryString, fn).FromJust(); | ||
| 380 | 342 | env->set_performance_entry_template(fn); | |
| 381 | 343 | ||
| 382 | 344 | env->SetMethod(target, "mark", Mark); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments