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 : PerformanceEntry(aParent
, aName
, u
"mark"_ns
),
21 mStartTime(aStartTime
),
23 mozilla::HoldJSObjects(this);
26 already_AddRefed
<PerformanceMark
> PerformanceMark::Constructor(
27 const GlobalObject
& aGlobal
, const nsAString
& aMarkName
,
28 const PerformanceMarkOptions
& aMarkOptions
, ErrorResult
& aRv
) {
29 const nsCOMPtr
<nsIGlobalObject
> global
=
30 do_QueryInterface(aGlobal
.GetAsSupports());
31 return PerformanceMark::Constructor(aGlobal
.Context(), global
, aMarkName
,
35 already_AddRefed
<PerformanceMark
> PerformanceMark::Constructor(
36 JSContext
* aCx
, nsIGlobalObject
* aGlobal
, const nsAString
& aMarkName
,
37 const PerformanceMarkOptions
& aMarkOptions
, ErrorResult
& aRv
) {
38 RefPtr
<Performance
> performance
= Performance::Get(aCx
, aGlobal
);
40 // This is similar to the message that occurs when accessing `performance`
41 // from outside a valid global.
43 "can't access PerformanceMark constructor, performance is null");
47 if (performance
->IsPerformanceTimingAttribute(aMarkName
)) {
48 aRv
.ThrowSyntaxError("markName cannot be a performance timing attribute");
52 DOMHighResTimeStamp startTime
= aMarkOptions
.mStartTime
.WasPassed()
53 ? aMarkOptions
.mStartTime
.Value()
56 aRv
.ThrowTypeError("Expected startTime >= 0");
60 JS::Rooted
<JS::Value
> detail(aCx
);
61 if (aMarkOptions
.mDetail
.isNullOrUndefined()) {
64 StructuredSerializeOptions serializeOptions
;
65 JS::Rooted
<JS::Value
> valueToClone(aCx
, aMarkOptions
.mDetail
);
66 nsContentUtils::StructuredClone(aCx
, aGlobal
, valueToClone
,
67 serializeOptions
, &detail
, aRv
);
73 return do_AddRef(new PerformanceMark(aGlobal
, aMarkName
, startTime
, detail
));
76 PerformanceMark::~PerformanceMark() { mozilla::DropJSObjects(this); }
78 NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMark
)
79 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMark
,
81 tmp
->mDetail
.setUndefined();
82 mozilla::DropJSObjects(tmp
);
83 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
84 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMark
,
86 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
88 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMark
,
90 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail
)
91 NS_IMPL_CYCLE_COLLECTION_TRACE_END
93 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(PerformanceMark
,
96 JSObject
* PerformanceMark::WrapObject(JSContext
* aCx
,
97 JS::Handle
<JSObject
*> aGivenProto
) {
98 return PerformanceMark_Binding::Wrap(aCx
, this, aGivenProto
);
101 void PerformanceMark::GetDetail(JSContext
* aCx
,
102 JS::MutableHandle
<JS::Value
> aRetval
) {
103 // Return a copy so that this method always returns the value it is set to
104 // (i.e. it'll return the same value even if the caller assigns to it). Note
105 // that if detail is an object, its contents can be mutated and this is
107 aRetval
.set(mDetail
);
110 size_t PerformanceMark::SizeOfIncludingThis(
111 mozilla::MallocSizeOf aMallocSizeOf
) const {
112 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);