1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "PerformanceMark.h"
8 #include "MainThreadUtils.h"
9 #include "nsContentUtils.h"
10 #include "Performance.h"
11 #include "mozilla/dom/MessagePortBinding.h"
12 #include "mozilla/dom/PerformanceBinding.h"
13 #include "mozilla/dom/PerformanceMarkBinding.h"
15 using namespace mozilla::dom
;
17 PerformanceMark::PerformanceMark(nsISupports
* aParent
, const nsAString
& aName
,
18 DOMHighResTimeStamp aStartTime
,
19 const JS::Handle
<JS::Value
>& aDetail
,
20 DOMHighResTimeStamp aUnclampedStartTime
)
21 : PerformanceEntry(aParent
, aName
, u
"mark"_ns
),
22 mStartTime(aStartTime
),
24 mUnclampedStartTime(aUnclampedStartTime
) {
25 mozilla::HoldJSObjects(this);
28 already_AddRefed
<PerformanceMark
> PerformanceMark::Constructor(
29 const GlobalObject
& aGlobal
, const nsAString
& aMarkName
,
30 const PerformanceMarkOptions
& aMarkOptions
, ErrorResult
& aRv
) {
31 const nsCOMPtr
<nsIGlobalObject
> global
=
32 do_QueryInterface(aGlobal
.GetAsSupports());
33 return PerformanceMark::Constructor(aGlobal
.Context(), global
, aMarkName
,
37 already_AddRefed
<PerformanceMark
> PerformanceMark::Constructor(
38 JSContext
* aCx
, nsIGlobalObject
* aGlobal
, const nsAString
& aMarkName
,
39 const PerformanceMarkOptions
& aMarkOptions
, ErrorResult
& aRv
) {
40 RefPtr
<Performance
> performance
= Performance::Get(aCx
, aGlobal
);
42 // This is similar to the message that occurs when accessing `performance`
43 // from outside a valid global.
45 "can't access PerformanceMark constructor, performance is null");
49 if (performance
->IsGlobalObjectWindow() &&
50 performance
->IsPerformanceTimingAttribute(aMarkName
)) {
51 aRv
.ThrowSyntaxError("markName cannot be a performance timing attribute");
55 DOMHighResTimeStamp startTime
= aMarkOptions
.mStartTime
.WasPassed()
56 ? aMarkOptions
.mStartTime
.Value()
58 // We need to get the unclamped start time to be able to add profiler markers
59 // with precise time/duration. This is not exposed to web and only used by the
61 // If a mStartTime is passed by the user, we will always have a clamped value.
62 DOMHighResTimeStamp unclampedStartTime
= aMarkOptions
.mStartTime
.WasPassed()
64 : performance
->NowUnclamped();
66 aRv
.ThrowTypeError("Expected startTime >= 0");
70 JS::Rooted
<JS::Value
> detail(aCx
);
71 if (aMarkOptions
.mDetail
.isNullOrUndefined()) {
74 StructuredSerializeOptions serializeOptions
;
75 JS::Rooted
<JS::Value
> valueToClone(aCx
, aMarkOptions
.mDetail
);
76 nsContentUtils::StructuredClone(aCx
, aGlobal
, valueToClone
,
77 serializeOptions
, &detail
, aRv
);
83 return do_AddRef(new PerformanceMark(aGlobal
, aMarkName
, startTime
, detail
,
87 PerformanceMark::~PerformanceMark() { mozilla::DropJSObjects(this); }
89 NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMark
)
90 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMark
,
92 tmp
->mDetail
.setUndefined();
93 mozilla::DropJSObjects(tmp
);
94 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
95 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMark
,
97 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
99 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMark
,
101 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail
)
102 NS_IMPL_CYCLE_COLLECTION_TRACE_END
104 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(PerformanceMark
,
107 JSObject
* PerformanceMark::WrapObject(JSContext
* aCx
,
108 JS::Handle
<JSObject
*> aGivenProto
) {
109 return PerformanceMark_Binding::Wrap(aCx
, this, aGivenProto
);
112 void PerformanceMark::GetDetail(JSContext
* aCx
,
113 JS::MutableHandle
<JS::Value
> aRetval
) {
114 // Return a copy so that this method always returns the value it is set to
115 // (i.e. it'll return the same value even if the caller assigns to it). Note
116 // that if detail is an object, its contents can be mutated and this is
118 aRetval
.set(mDetail
);
121 size_t PerformanceMark::SizeOfIncludingThis(
122 mozilla::MallocSizeOf aMallocSizeOf
) const {
123 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);