@sentry/profiling-node 8.8.0 → 8.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bindings/cpu_profiler.cc +155 -60
- package/lib/cjs/index.js +479 -154
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/index.js +478 -154
- package/lib/esm/index.js.map +1 -1
- package/lib/sentry_cpu_profiler-darwin-arm64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-127.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-93.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-127.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-93.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-127.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-93.node +0 -0
- package/lib/types/profiling-node/src/cpu_profiler.d.ts +16 -0
- package/lib/types/profiling-node/src/cpu_profiler.d.ts.map +1 -0
- package/lib/types/profiling-node/src/debug-build.d.ts.map +1 -0
- package/lib/types/profiling-node/src/index.d.ts.map +1 -0
- package/lib/types/profiling-node/src/integration.d.ts +57 -0
- package/lib/types/profiling-node/src/integration.d.ts.map +1 -0
- package/lib/types/profiling-node/src/nodeVersion.d.ts.map +1 -0
- package/lib/types/{spanProfileUtils.d.ts → profiling-node/src/spanProfileUtils.d.ts} +2 -2
- package/lib/types/profiling-node/src/spanProfileUtils.d.ts.map +1 -0
- package/lib/types/profiling-node/src/types.d.ts +60 -0
- package/lib/types/profiling-node/src/types.d.ts.map +1 -0
- package/lib/types/{utils.d.ts → profiling-node/src/utils.d.ts} +30 -4
- package/lib/types/profiling-node/src/utils.d.ts.map +1 -0
- package/lib/types/types/src/debugMeta.d.ts +28 -0
- package/lib/types/types/src/debugMeta.d.ts.map +1 -0
- package/lib/types/types/src/measurement.d.ts +24 -0
- package/lib/types/types/src/measurement.d.ts.map +1 -0
- package/lib/types/types/src/profiling.d.ts +126 -0
- package/lib/types/types/src/profiling.d.ts.map +1 -0
- package/lib/types-ts3.8/profiling-node/src/cpu_profiler.d.ts +16 -0
- package/lib/types-ts3.8/profiling-node/src/integration.d.ts +57 -0
- package/lib/types-ts3.8/{spanProfileUtils.d.ts → profiling-node/src/spanProfileUtils.d.ts} +2 -2
- package/lib/types-ts3.8/profiling-node/src/types.d.ts +60 -0
- package/lib/types-ts3.8/{utils.d.ts → profiling-node/src/utils.d.ts} +30 -4
- package/lib/types-ts3.8/types/src/debugMeta.d.ts +28 -0
- package/lib/types-ts3.8/types/src/measurement.d.ts +24 -0
- package/lib/types-ts3.8/types/src/profiling.d.ts +126 -0
- package/package.json +5 -5
- package/lib/types/cpu_profiler.d.ts +0 -10
- package/lib/types/cpu_profiler.d.ts.map +0 -1
- package/lib/types/debug-build.d.ts.map +0 -1
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/integration.d.ts +0 -14
- package/lib/types/integration.d.ts.map +0 -1
- package/lib/types/nodeVersion.d.ts.map +0 -1
- package/lib/types/spanProfileUtils.d.ts.map +0 -1
- package/lib/types/types.d.ts +0 -100
- package/lib/types/types.d.ts.map +0 -1
- package/lib/types/utils.d.ts.map +0 -1
- package/lib/types-ts3.8/cpu_profiler.d.ts +0 -10
- package/lib/types-ts3.8/integration.d.ts +0 -14
- package/lib/types-ts3.8/types.d.ts +0 -100
- /package/lib/types/{debug-build.d.ts → profiling-node/src/debug-build.d.ts} +0 -0
- /package/lib/types/{index.d.ts → profiling-node/src/index.d.ts} +0 -0
- /package/lib/types/{nodeVersion.d.ts → profiling-node/src/nodeVersion.d.ts} +0 -0
- /package/lib/types-ts3.8/{debug-build.d.ts → profiling-node/src/debug-build.d.ts} +0 -0
- /package/lib/types-ts3.8/{index.d.ts → profiling-node/src/index.d.ts} +0 -0
- /package/lib/types-ts3.8/{nodeVersion.d.ts → profiling-node/src/nodeVersion.d.ts} +0 -0
package/bindings/cpu_profiler.cc
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include <v8-profiler.h>
|
|
11
11
|
#include <v8.h>
|
|
12
12
|
|
|
13
|
+
#include <chrono>
|
|
13
14
|
#include <functional>
|
|
14
15
|
#include <string>
|
|
15
16
|
#include <unordered_map>
|
|
@@ -23,6 +24,10 @@ static const v8::CpuProfilingNamingMode
|
|
|
23
24
|
static const v8::CpuProfilingLoggingMode
|
|
24
25
|
kDefaultLoggingMode(v8::CpuProfilingLoggingMode::kEagerLogging);
|
|
25
26
|
|
|
27
|
+
enum ProfileFormat {
|
|
28
|
+
kFormatThread = 0,
|
|
29
|
+
kFormatChunk = 1,
|
|
30
|
+
};
|
|
26
31
|
// Allow users to override the default logging mode via env variable. This is
|
|
27
32
|
// useful because sometimes the flow of the profiled program can be to execute
|
|
28
33
|
// many sequential transaction - in that case, it may be preferable to set eager
|
|
@@ -50,6 +55,12 @@ v8::CpuProfilingLoggingMode GetLoggingMode() {
|
|
|
50
55
|
return kDefaultLoggingMode;
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
uint64_t timestamp_milliseconds() {
|
|
59
|
+
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
60
|
+
std::chrono::system_clock::now().time_since_epoch())
|
|
61
|
+
.count();
|
|
62
|
+
}
|
|
63
|
+
|
|
53
64
|
class SentryProfile;
|
|
54
65
|
class Profiler;
|
|
55
66
|
|
|
@@ -241,6 +252,7 @@ public:
|
|
|
241
252
|
class SentryProfile {
|
|
242
253
|
private:
|
|
243
254
|
uint64_t started_at;
|
|
255
|
+
uint64_t timestamp;
|
|
244
256
|
uint16_t heap_write_index = 0;
|
|
245
257
|
uint16_t cpu_write_index = 0;
|
|
246
258
|
|
|
@@ -258,7 +270,7 @@ private:
|
|
|
258
270
|
|
|
259
271
|
public:
|
|
260
272
|
explicit SentryProfile(const char *id)
|
|
261
|
-
: started_at(uv_hrtime()),
|
|
273
|
+
: started_at(uv_hrtime()), timestamp(timestamp_milliseconds()),
|
|
262
274
|
memory_sampler_cb([this](uint64_t ts, v8::HeapStatistics &stats) {
|
|
263
275
|
if ((heap_write_index >= heap_stats_ts.capacity()) ||
|
|
264
276
|
heap_write_index >= heap_stats_usage.capacity()) {
|
|
@@ -302,6 +314,7 @@ public:
|
|
|
302
314
|
const std::vector<uint64_t> &cpu_usage_timestamps() const;
|
|
303
315
|
const std::vector<double> &cpu_usage_values() const;
|
|
304
316
|
const uint16_t &cpu_usage_write_index() const;
|
|
317
|
+
const uint64_t &profile_start_timestamp() const;
|
|
305
318
|
|
|
306
319
|
void Start(Profiler *profiler);
|
|
307
320
|
v8::CpuProfile *Stop(Profiler *profiler);
|
|
@@ -314,6 +327,7 @@ void SentryProfile::Start(Profiler *profiler) {
|
|
|
314
327
|
.ToLocalChecked();
|
|
315
328
|
|
|
316
329
|
started_at = uv_hrtime();
|
|
330
|
+
timestamp = timestamp_milliseconds();
|
|
317
331
|
|
|
318
332
|
// Initialize the CPU Profiler
|
|
319
333
|
profiler->cpu_profiler->StartProfiling(
|
|
@@ -368,6 +382,9 @@ const std::vector<double> &SentryProfile::cpu_usage_values() const {
|
|
|
368
382
|
const uint16_t &SentryProfile::cpu_usage_write_index() const {
|
|
369
383
|
return cpu_write_index;
|
|
370
384
|
};
|
|
385
|
+
const uint64_t &SentryProfile::profile_start_timestamp() const {
|
|
386
|
+
return timestamp;
|
|
387
|
+
}
|
|
371
388
|
|
|
372
389
|
static void CleanupSentryProfile(Profiler *profiler,
|
|
373
390
|
SentryProfile *sentry_profile,
|
|
@@ -528,8 +545,9 @@ CreateFrameNode(const napi_env &env, const v8::CpuProfileNode &node,
|
|
|
528
545
|
return js_node;
|
|
529
546
|
};
|
|
530
547
|
|
|
531
|
-
napi_value CreateSample(const napi_env &env, const
|
|
532
|
-
const int64_t
|
|
548
|
+
napi_value CreateSample(const napi_env &env, const enum ProfileFormat format,
|
|
549
|
+
const uint32_t stack_id, const int64_t sample_timestamp,
|
|
550
|
+
const double chunk_timestamp,
|
|
533
551
|
const uint32_t thread_id) {
|
|
534
552
|
napi_value js_node;
|
|
535
553
|
napi_create_object(env, &js_node);
|
|
@@ -543,11 +561,20 @@ napi_value CreateSample(const napi_env &env, const uint32_t stack_id,
|
|
|
543
561
|
NAPI_AUTO_LENGTH, &thread_id_prop);
|
|
544
562
|
napi_set_named_property(env, js_node, "thread_id", thread_id_prop);
|
|
545
563
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
564
|
+
switch (format) {
|
|
565
|
+
case ProfileFormat::kFormatThread: {
|
|
566
|
+
napi_value timestamp;
|
|
567
|
+
napi_create_int64(env, sample_timestamp, ×tamp);
|
|
568
|
+
napi_set_named_property(env, js_node, "elapsed_since_start_ns", timestamp);
|
|
569
|
+
} break;
|
|
570
|
+
case ProfileFormat::kFormatChunk: {
|
|
571
|
+
napi_value timestamp;
|
|
572
|
+
napi_create_double(env, chunk_timestamp, ×tamp);
|
|
573
|
+
napi_set_named_property(env, js_node, "timestamp", timestamp);
|
|
574
|
+
} break;
|
|
575
|
+
default:
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
551
578
|
|
|
552
579
|
return js_node;
|
|
553
580
|
};
|
|
@@ -566,11 +593,13 @@ std::string hashCpuProfilerNodeByPath(const v8::CpuProfileNode *node,
|
|
|
566
593
|
}
|
|
567
594
|
|
|
568
595
|
static void GetSamples(const napi_env &env, const v8::CpuProfile *profile,
|
|
596
|
+
ProfileFormat format,
|
|
597
|
+
const uint64_t profile_start_timestamp_ms,
|
|
569
598
|
const uint32_t thread_id, napi_value &samples,
|
|
570
599
|
napi_value &stacks, napi_value &frames,
|
|
571
600
|
napi_value &resources) {
|
|
572
601
|
const int64_t profile_start_time_us = profile->GetStartTime();
|
|
573
|
-
const
|
|
602
|
+
const int64_t sampleCount = profile->GetSamplesCount();
|
|
574
603
|
|
|
575
604
|
uint32_t unique_stack_id = 0;
|
|
576
605
|
uint32_t unique_frame_id = 0;
|
|
@@ -590,7 +619,7 @@ static void GetSamples(const napi_env &env, const v8::CpuProfile *profile,
|
|
|
590
619
|
uint32_t stack_index = unique_stack_id;
|
|
591
620
|
|
|
592
621
|
const v8::CpuProfileNode *node = profile->GetSample(i);
|
|
593
|
-
const int64_t
|
|
622
|
+
const int64_t sample_timestamp_us = profile->GetSampleTimestamp(i);
|
|
594
623
|
|
|
595
624
|
// If a node was only on top of the stack once, then it will only ever
|
|
596
625
|
// be inserted once and there is no need for hashing.
|
|
@@ -609,8 +638,16 @@ static void GetSamples(const napi_env &env, const v8::CpuProfile *profile,
|
|
|
609
638
|
}
|
|
610
639
|
}
|
|
611
640
|
|
|
612
|
-
|
|
613
|
-
|
|
641
|
+
uint64_t sample_delta_us = sample_timestamp_us - profile_start_time_us;
|
|
642
|
+
uint64_t sample_timestamp_ns = sample_delta_us * 1e3;
|
|
643
|
+
uint64_t sample_offset_from_profile_start_ms =
|
|
644
|
+
(sample_timestamp_us - profile_start_time_us) * 1e-3;
|
|
645
|
+
double seconds_since_start =
|
|
646
|
+
profile_start_timestamp_ms + sample_offset_from_profile_start_ms;
|
|
647
|
+
|
|
648
|
+
napi_value sample = nullptr;
|
|
649
|
+
sample = CreateSample(env, format, stack_index, sample_timestamp_ns,
|
|
650
|
+
seconds_since_start, thread_id);
|
|
614
651
|
|
|
615
652
|
if (stack_index != unique_stack_id) {
|
|
616
653
|
napi_value index;
|
|
@@ -671,19 +708,19 @@ static void GetSamples(const napi_env &env, const v8::CpuProfile *profile,
|
|
|
671
708
|
}
|
|
672
709
|
}
|
|
673
710
|
|
|
674
|
-
static napi_value
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if (size > values.size() || size >
|
|
711
|
+
static napi_value TranslateMeasurementsDouble(
|
|
712
|
+
const napi_env &env, const enum ProfileFormat format, const char *unit,
|
|
713
|
+
const uint64_t profile_start_timestamp_ms, const uint16_t size,
|
|
714
|
+
const std::vector<double> &values,
|
|
715
|
+
const std::vector<uint64_t> ×tamps_ns) {
|
|
716
|
+
if (size > values.size() || size > timestamps_ns.size()) {
|
|
680
717
|
napi_throw_range_error(env, "NAPI_ERROR",
|
|
681
718
|
"CPU measurement size is larger than the number of "
|
|
682
719
|
"values or timestamps");
|
|
683
720
|
return nullptr;
|
|
684
721
|
}
|
|
685
722
|
|
|
686
|
-
if (values.size() !=
|
|
723
|
+
if (values.size() != timestamps_ns.size()) {
|
|
687
724
|
napi_throw_range_error(env, "NAPI_ERROR",
|
|
688
725
|
"CPU measurement entries are corrupt, expected "
|
|
689
726
|
"values and timestamps to be of equal length");
|
|
@@ -713,11 +750,19 @@ TranslateMeasurementsDouble(const napi_env &env, const char *unit,
|
|
|
713
750
|
}
|
|
714
751
|
}
|
|
715
752
|
|
|
716
|
-
napi_value ts;
|
|
717
|
-
napi_create_int64(env, timestamps[i], &ts);
|
|
718
|
-
|
|
719
753
|
napi_set_named_property(env, entry, "value", value);
|
|
720
|
-
|
|
754
|
+
|
|
755
|
+
if (format == ProfileFormat::kFormatThread) {
|
|
756
|
+
napi_value ts;
|
|
757
|
+
napi_create_int64(env, timestamps_ns[i], &ts);
|
|
758
|
+
napi_set_named_property(env, entry, "elapsed_since_start_ns", ts);
|
|
759
|
+
} else if (format == ProfileFormat::kFormatChunk) {
|
|
760
|
+
napi_value ts;
|
|
761
|
+
napi_create_double(
|
|
762
|
+
env, profile_start_timestamp_ms + (timestamps_ns[i] * 1e-6), &ts);
|
|
763
|
+
napi_set_named_property(env, entry, "timestamp", ts);
|
|
764
|
+
}
|
|
765
|
+
|
|
721
766
|
napi_set_element(env, values_array, i, entry);
|
|
722
767
|
}
|
|
723
768
|
|
|
@@ -727,17 +772,19 @@ TranslateMeasurementsDouble(const napi_env &env, const char *unit,
|
|
|
727
772
|
}
|
|
728
773
|
|
|
729
774
|
static napi_value
|
|
730
|
-
TranslateMeasurements(const napi_env &env, const
|
|
775
|
+
TranslateMeasurements(const napi_env &env, const enum ProfileFormat format,
|
|
776
|
+
const char *unit,
|
|
777
|
+
const uint64_t profile_start_timestamp_ms,
|
|
731
778
|
const uint16_t size, const std::vector<uint64_t> &values,
|
|
732
|
-
const std::vector<uint64_t> &
|
|
733
|
-
if (size > values.size() || size >
|
|
779
|
+
const std::vector<uint64_t> ×tamps_ns) {
|
|
780
|
+
if (size > values.size() || size > timestamps_ns.size()) {
|
|
734
781
|
napi_throw_range_error(env, "NAPI_ERROR",
|
|
735
782
|
"Memory measurement size is larger than the number "
|
|
736
783
|
"of values or timestamps");
|
|
737
784
|
return nullptr;
|
|
738
785
|
}
|
|
739
786
|
|
|
740
|
-
if (values.size() !=
|
|
787
|
+
if (values.size() != timestamps_ns.size()) {
|
|
741
788
|
napi_throw_range_error(env, "NAPI_ERROR",
|
|
742
789
|
"Memory measurement entries are corrupt, expected "
|
|
743
790
|
"values and timestamps to be of equal length");
|
|
@@ -761,11 +808,22 @@ TranslateMeasurements(const napi_env &env, const char *unit,
|
|
|
761
808
|
napi_value value;
|
|
762
809
|
napi_create_int64(env, values[i], &value);
|
|
763
810
|
|
|
764
|
-
napi_value ts;
|
|
765
|
-
napi_create_int64(env, timestamps[i], &ts);
|
|
766
|
-
|
|
767
811
|
napi_set_named_property(env, entry, "value", value);
|
|
768
|
-
|
|
812
|
+
switch (format) {
|
|
813
|
+
case ProfileFormat::kFormatThread: {
|
|
814
|
+
napi_value ts;
|
|
815
|
+
napi_create_int64(env, timestamps_ns[i], &ts);
|
|
816
|
+
napi_set_named_property(env, entry, "elapsed_since_start_ns", ts);
|
|
817
|
+
} break;
|
|
818
|
+
case ProfileFormat::kFormatChunk: {
|
|
819
|
+
napi_value ts;
|
|
820
|
+
napi_create_double(
|
|
821
|
+
env, profile_start_timestamp_ms + (timestamps_ns[i] * 1e-6), &ts);
|
|
822
|
+
napi_set_named_property(env, entry, "timestamp", ts);
|
|
823
|
+
} break;
|
|
824
|
+
default:
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
769
827
|
napi_set_element(env, values_array, i, entry);
|
|
770
828
|
}
|
|
771
829
|
|
|
@@ -776,6 +834,8 @@ TranslateMeasurements(const napi_env &env, const char *unit,
|
|
|
776
834
|
|
|
777
835
|
static napi_value TranslateProfile(const napi_env &env,
|
|
778
836
|
const v8::CpuProfile *profile,
|
|
837
|
+
const enum ProfileFormat format,
|
|
838
|
+
const uint64_t profile_start_timestamp_ms,
|
|
779
839
|
const uint32_t thread_id,
|
|
780
840
|
bool collect_resources) {
|
|
781
841
|
napi_value js_profile;
|
|
@@ -805,7 +865,8 @@ static napi_value TranslateProfile(const napi_env &env,
|
|
|
805
865
|
napi_set_named_property(env, js_profile, "profiler_logging_mode",
|
|
806
866
|
logging_mode);
|
|
807
867
|
|
|
808
|
-
GetSamples(env, profile,
|
|
868
|
+
GetSamples(env, profile, format, profile_start_timestamp_ms, thread_id,
|
|
869
|
+
samples, stacks, frames, resources);
|
|
809
870
|
|
|
810
871
|
if (collect_resources) {
|
|
811
872
|
napi_set_named_property(env, js_profile, "resources", resources);
|
|
@@ -892,14 +953,14 @@ static napi_value StartProfiling(napi_env env, napi_callback_info info) {
|
|
|
892
953
|
// StopProfiling(string title)
|
|
893
954
|
// https://v8docs.nodesource.com/node-18.2/d2/d34/classv8_1_1_cpu_profiler.html#a40ca4c8a8aa4c9233aa2a2706457cc80
|
|
894
955
|
static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
895
|
-
size_t argc =
|
|
896
|
-
napi_value argv[
|
|
956
|
+
size_t argc = 4;
|
|
957
|
+
napi_value argv[4];
|
|
897
958
|
|
|
898
959
|
assert(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok);
|
|
899
960
|
|
|
900
|
-
if (argc <
|
|
961
|
+
if (argc < 3) {
|
|
901
962
|
napi_throw_error(env, "NAPI_ERROR",
|
|
902
|
-
"StopProfiling expects at least
|
|
963
|
+
"StopProfiling expects at least three arguments.");
|
|
903
964
|
|
|
904
965
|
napi_value napi_null;
|
|
905
966
|
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
@@ -921,14 +982,17 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
921
982
|
return napi_null;
|
|
922
983
|
}
|
|
923
984
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
assert(napi_typeof(env, argv[1], &callbacktype1) == napi_ok);
|
|
985
|
+
size_t len;
|
|
986
|
+
assert(napi_get_value_string_utf8(env, argv[0], NULL, 0, &len) == napi_ok);
|
|
927
987
|
|
|
928
|
-
|
|
988
|
+
char *title = (char *)malloc(len + 1);
|
|
989
|
+
assert(napi_get_value_string_utf8(env, argv[0], title, len + 1, &len) ==
|
|
990
|
+
napi_ok);
|
|
991
|
+
|
|
992
|
+
if (len < 1) {
|
|
929
993
|
napi_throw_error(
|
|
930
994
|
env, "NAPI_ERROR",
|
|
931
|
-
"StopProfiling expects a
|
|
995
|
+
"StopProfiling expects a non empty string as first argument.");
|
|
932
996
|
|
|
933
997
|
napi_value napi_null;
|
|
934
998
|
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
@@ -936,16 +1000,13 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
936
1000
|
return napi_null;
|
|
937
1001
|
}
|
|
938
1002
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
char *title = (char *)malloc(len + 1);
|
|
943
|
-
assert(napi_get_value_string_utf8(env, argv[0], title, len + 1, &len) ==
|
|
944
|
-
napi_ok);
|
|
1003
|
+
// Verify the second argument is a number
|
|
1004
|
+
napi_valuetype callbacktype1;
|
|
1005
|
+
assert(napi_typeof(env, argv[1], &callbacktype1) == napi_ok);
|
|
945
1006
|
|
|
946
|
-
if (
|
|
1007
|
+
if (callbacktype1 != napi_number) {
|
|
947
1008
|
napi_throw_error(env, "NAPI_ERROR",
|
|
948
|
-
"StopProfiling expects a
|
|
1009
|
+
"StopProfiling expects a format type as second argument.");
|
|
949
1010
|
|
|
950
1011
|
napi_value napi_null;
|
|
951
1012
|
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
@@ -953,9 +1014,27 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
953
1014
|
return napi_null;
|
|
954
1015
|
}
|
|
955
1016
|
|
|
1017
|
+
// Verify the second argument is a number
|
|
1018
|
+
napi_valuetype callbacktype2;
|
|
1019
|
+
assert(napi_typeof(env, argv[2], &callbacktype2) == napi_ok);
|
|
1020
|
+
|
|
1021
|
+
if (callbacktype2 != napi_number) {
|
|
1022
|
+
napi_throw_error(
|
|
1023
|
+
env, "NAPI_ERROR",
|
|
1024
|
+
"StopProfiling expects a thread_id integer as third argument.");
|
|
1025
|
+
|
|
1026
|
+
napi_value napi_null;
|
|
1027
|
+
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
1028
|
+
return napi_null;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Get the value of the second argument and convert it to uint8
|
|
1032
|
+
int32_t format;
|
|
1033
|
+
assert(napi_get_value_int32(env, argv[1], &format) == napi_ok);
|
|
1034
|
+
|
|
956
1035
|
// Get the value of the second argument and convert it to uint64
|
|
957
1036
|
int64_t thread_id;
|
|
958
|
-
assert(napi_get_value_int64(env, argv[
|
|
1037
|
+
assert(napi_get_value_int64(env, argv[2], &thread_id) == napi_ok);
|
|
959
1038
|
|
|
960
1039
|
// Get profiler from instance data
|
|
961
1040
|
Profiler *profiler;
|
|
@@ -967,7 +1046,6 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
967
1046
|
|
|
968
1047
|
napi_value napi_null;
|
|
969
1048
|
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
970
|
-
|
|
971
1049
|
return napi_null;
|
|
972
1050
|
}
|
|
973
1051
|
|
|
@@ -994,23 +1072,39 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
994
1072
|
};
|
|
995
1073
|
|
|
996
1074
|
napi_valuetype callbacktype3;
|
|
997
|
-
assert(napi_typeof(env, argv[
|
|
1075
|
+
assert(napi_typeof(env, argv[3], &callbacktype3) == napi_ok);
|
|
998
1076
|
|
|
999
1077
|
bool collect_resources;
|
|
1000
|
-
napi_get_value_bool(env, argv[
|
|
1078
|
+
napi_get_value_bool(env, argv[3], &collect_resources);
|
|
1079
|
+
|
|
1080
|
+
const ProfileFormat format_type = static_cast<ProfileFormat>(format);
|
|
1081
|
+
|
|
1082
|
+
if (format_type != ProfileFormat::kFormatThread &&
|
|
1083
|
+
format_type != ProfileFormat::kFormatChunk) {
|
|
1084
|
+
napi_throw_error(
|
|
1085
|
+
env, "NAPI_ERROR",
|
|
1086
|
+
"StopProfiling expects a valid format type as second argument.");
|
|
1087
|
+
|
|
1088
|
+
napi_value napi_null;
|
|
1089
|
+
assert(napi_get_null(env, &napi_null) == napi_ok);
|
|
1090
|
+
return napi_null;
|
|
1091
|
+
}
|
|
1001
1092
|
|
|
1002
|
-
napi_value js_profile =
|
|
1003
|
-
|
|
1093
|
+
napi_value js_profile = TranslateProfile(
|
|
1094
|
+
env, cpu_profile, format_type, profile->second->profile_start_timestamp(),
|
|
1095
|
+
thread_id, collect_resources);
|
|
1004
1096
|
|
|
1005
1097
|
napi_value measurements;
|
|
1006
1098
|
napi_create_object(env, &measurements);
|
|
1007
1099
|
|
|
1008
1100
|
if (profile->second->heap_usage_write_index() > 0) {
|
|
1009
1101
|
static const char *memory_unit = "byte";
|
|
1010
|
-
napi_value heap_usage_measurements =
|
|
1011
|
-
env,
|
|
1012
|
-
|
|
1013
|
-
|
|
1102
|
+
napi_value heap_usage_measurements =
|
|
1103
|
+
TranslateMeasurements(env, format_type, memory_unit,
|
|
1104
|
+
profile->second->profile_start_timestamp(),
|
|
1105
|
+
profile->second->heap_usage_write_index(),
|
|
1106
|
+
profile->second->heap_usage_values(),
|
|
1107
|
+
profile->second->heap_usage_timestamps());
|
|
1014
1108
|
|
|
1015
1109
|
if (heap_usage_measurements != nullptr) {
|
|
1016
1110
|
napi_set_named_property(env, measurements, "memory_footprint",
|
|
@@ -1021,7 +1115,8 @@ static napi_value StopProfiling(napi_env env, napi_callback_info info) {
|
|
|
1021
1115
|
if (profile->second->cpu_usage_write_index() > 0) {
|
|
1022
1116
|
static const char *cpu_unit = "percent";
|
|
1023
1117
|
napi_value cpu_usage_measurements = TranslateMeasurementsDouble(
|
|
1024
|
-
env, cpu_unit, profile->second->
|
|
1118
|
+
env, format_type, cpu_unit, profile->second->profile_start_timestamp(),
|
|
1119
|
+
profile->second->cpu_usage_write_index(),
|
|
1025
1120
|
profile->second->cpu_usage_values(),
|
|
1026
1121
|
profile->second->cpu_usage_timestamps());
|
|
1027
1122
|
|