Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / performance / PerformanceMark.cpp
blob57258e210746f2858326184059c94deb0f6d3f00
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),
23 mDetail(aDetail),
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,
34 aMarkOptions, aRv);
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);
41 if (!performance) {
42 // This is similar to the message that occurs when accessing `performance`
43 // from outside a valid global.
44 aRv.ThrowTypeError(
45 "can't access PerformanceMark constructor, performance is null");
46 return nullptr;
49 if (performance->IsGlobalObjectWindow() &&
50 performance->IsPerformanceTimingAttribute(aMarkName)) {
51 aRv.ThrowSyntaxError("markName cannot be a performance timing attribute");
52 return nullptr;
55 DOMHighResTimeStamp startTime = aMarkOptions.mStartTime.WasPassed()
56 ? aMarkOptions.mStartTime.Value()
57 : performance->Now();
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
60 // profiler.
61 // If a mStartTime is passed by the user, we will always have a clamped value.
62 DOMHighResTimeStamp unclampedStartTime = aMarkOptions.mStartTime.WasPassed()
63 ? startTime
64 : performance->NowUnclamped();
65 if (startTime < 0) {
66 aRv.ThrowTypeError("Expected startTime >= 0");
67 return nullptr;
70 JS::Rooted<JS::Value> detail(aCx);
71 if (aMarkOptions.mDetail.isNullOrUndefined()) {
72 detail.setNull();
73 } else {
74 StructuredSerializeOptions serializeOptions;
75 JS::Rooted<JS::Value> valueToClone(aCx, aMarkOptions.mDetail);
76 nsContentUtils::StructuredClone(aCx, aGlobal, valueToClone,
77 serializeOptions, &detail, aRv);
78 if (aRv.Failed()) {
79 return nullptr;
83 return do_AddRef(new PerformanceMark(aGlobal, aMarkName, startTime, detail,
84 unclampedStartTime));
87 PerformanceMark::~PerformanceMark() { mozilla::DropJSObjects(this); }
89 NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMark)
90 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMark,
91 PerformanceEntry)
92 tmp->mDetail.setUndefined();
93 mozilla::DropJSObjects(tmp);
94 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
95 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMark,
96 PerformanceEntry)
97 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
99 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMark,
100 PerformanceEntry)
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,
105 PerformanceEntry)
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
117 // expected.
118 aRetval.set(mDetail);
121 size_t PerformanceMark::SizeOfIncludingThis(
122 mozilla::MallocSizeOf aMallocSizeOf) const {
123 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);