ProfilingSources.h (5936B)
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/. */ 6 7 #ifndef js_ProfilingSources_h 8 #define js_ProfilingSources_h 9 10 #include "mozilla/Variant.h" 11 12 #include <stdint.h> 13 14 #include "jstypes.h" 15 16 #include "js/TypeDecls.h" 17 #include "js/Utility.h" 18 #include "js/Vector.h" 19 20 /* 21 * Struct to pass JS source data with content type information for profiler use. 22 */ 23 struct JS_PUBLIC_API ProfilerJSSourceData { 24 public: 25 struct SourceTextUTF16 { 26 public: 27 SourceTextUTF16(JS::UniqueTwoByteChars&& c, size_t l) 28 : chars_(std::move(c)), length_(l) {} 29 30 const JS::UniqueTwoByteChars& chars() const { return chars_; } 31 size_t length() const { return length_; } 32 33 private: 34 // Not null-terminated string for source text. Always use it with the 35 // length. 36 JS::UniqueTwoByteChars chars_; 37 size_t length_; 38 }; 39 40 struct SourceTextUTF8 { 41 public: 42 SourceTextUTF8(JS::UniqueChars&& c, size_t l) 43 : chars_(std::move(c)), length_(l) {} 44 45 const JS::UniqueChars& chars() const { return chars_; } 46 size_t length() const { return length_; } 47 48 private: 49 // Not null-terminated string for source text. Always use it with the 50 // length. 51 JS::UniqueChars chars_; 52 size_t length_; 53 }; 54 55 /* 56 * Represents a source file that can be retrieved later in the parent process. 57 * Used when source text is not immediately available in the current process 58 * but can be fetched using the file path information. 59 */ 60 struct RetrievableFile {}; 61 62 struct Unavailable {}; 63 64 using ProfilerSourceVariant = 65 mozilla::Variant<SourceTextUTF16, SourceTextUTF8, RetrievableFile, 66 Unavailable>; 67 68 // Constructors 69 ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& filePath, 70 size_t pathLen) 71 : sourceId_(sourceId), 72 filePath_(std::move(filePath)), 73 filePathLength_(pathLen), 74 data_(Unavailable{}) {} 75 76 // UTF-8 source text with filePath 77 ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& chars, 78 size_t length, JS::UniqueChars&& filePath, 79 size_t pathLen) 80 : sourceId_(sourceId), 81 filePath_(std::move(filePath)), 82 filePathLength_(pathLen), 83 data_(SourceTextUTF8{std::move(chars), length}) {} 84 85 // UTF-16 source text with filePath 86 ProfilerJSSourceData(uint32_t sourceId, JS::UniqueTwoByteChars&& chars, 87 size_t length, JS::UniqueChars&& filePath, 88 size_t pathLen) 89 : sourceId_(sourceId), 90 filePath_(std::move(filePath)), 91 filePathLength_(pathLen), 92 data_(SourceTextUTF16{std::move(chars), length}) {} 93 94 // For the cases where no sourceId and filepath are needed. 95 ProfilerJSSourceData(JS::UniqueChars&& chars, size_t length) 96 : sourceId_(0), 97 filePath_(nullptr), 98 filePathLength_(0), 99 data_(SourceTextUTF8{std::move(chars), length}) {} 100 101 ProfilerJSSourceData() 102 : sourceId_(0), filePathLength_(0), data_(Unavailable{}) {} 103 104 static ProfilerJSSourceData CreateRetrievableFile(uint32_t sourceId, 105 JS::UniqueChars&& filePath, 106 size_t pathLength) { 107 ProfilerJSSourceData result(sourceId, std::move(filePath), pathLength); 108 result.data_.emplace<RetrievableFile>(); 109 return result; 110 } 111 112 ProfilerJSSourceData(ProfilerJSSourceData&&) = default; 113 ProfilerJSSourceData& operator=(ProfilerJSSourceData&&) = default; 114 115 // No copy constructors as this class owns its string storage. 116 ProfilerJSSourceData(const ProfilerJSSourceData& other) = delete; 117 ProfilerJSSourceData& operator=(const ProfilerJSSourceData&) = delete; 118 119 uint32_t sourceId() const { return sourceId_; } 120 // Consumer should always check for filePathLength before calling this. 121 const char* filePath() const { 122 MOZ_ASSERT(filePath_); 123 return filePath_.get(); 124 } 125 size_t filePathLength() const { return filePathLength_; } 126 const ProfilerSourceVariant& data() const { return data_; } 127 128 // Used only for memory reporting. 129 size_t SizeOf() const { 130 // Size of sourceId + filepath 131 size_t size = sizeof(uint32_t) + filePathLength_ * sizeof(char); 132 133 data_.match( 134 [&](const SourceTextUTF16& srcText) { 135 size += srcText.length() * sizeof(char16_t); 136 }, 137 [&](const SourceTextUTF8& srcText) { 138 size += srcText.length() * sizeof(char); 139 }, 140 [](const RetrievableFile&) {}, [](const Unavailable&) {}); 141 142 return size; 143 } 144 145 private: 146 // Unique identifier for this source across the process. This can be used 147 // to refer to this source from places that don't want to hold a strong 148 // reference on the source itself. 149 // Generated by ScriptSource and retrieved via ScriptSource::id(). See 150 // ScriptSource::id_ for more details. 151 uint32_t sourceId_; 152 // Null-terminated file path for the source. 153 // It can be nullptr if: 154 // - The source has no filename. 155 // - filename allocation fails during copy. 156 JS::UniqueChars filePath_; 157 size_t filePathLength_; 158 ProfilerSourceVariant data_; 159 }; 160 161 namespace js { 162 163 using ProfilerJSSources = 164 js::Vector<ProfilerJSSourceData, 0, js::SystemAllocPolicy>; 165 166 /* 167 * Main API for getting the profiled JS sources. 168 */ 169 JS_PUBLIC_API ProfilerJSSources GetProfilerScriptSources(JSRuntime* rt); 170 171 /** 172 * Retrieve the JS sources that are only retrievable from the parent process. 173 * See RetrievableFile struct for more information. 174 * */ 175 JS_PUBLIC_API ProfilerJSSourceData 176 RetrieveProfilerSourceContent(JSContext* cx, const char* filename); 177 178 } // namespace js 179 180 #endif /* js_ProfilingSources_h */