1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* IOInterposeObserver recording statistics of main-thread I/O during execution,
* aimed at consumption by TelemetryImpl
*/
#ifndef TelemetryIOInterposeObserver_h__
#define TelemetryIOInterposeObserver_h__
#include "core/TelemetryCommon.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
#include "mozilla/IOInterposer.h"
#include "nsBaseHashtable.h"
#include "nsHashKeys.h"
#include "nsTArray.h"
namespace mozilla {
namespace Telemetry {
class TelemetryIOInterposeObserver : public IOInterposeObserver {
/** File-level statistics structure */
struct FileStats {
FileStats()
: creates(0), reads(0), writes(0), fsyncs(0), stats(0), totalTime(0) {}
uint32_t creates; /** Number of create/open operations */
uint32_t reads; /** Number of read operations */
uint32_t writes; /** Number of write operations */
uint32_t fsyncs; /** Number of fsync operations */
uint32_t stats; /** Number of stat operations */
double totalTime; /** Accumulated duration of all operations */
};
struct SafeDir {
SafeDir(const nsAString& aPath, const nsAString& aSubstName)
: mPath(aPath), mSubstName(aSubstName) {}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
mSubstName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
nsString mPath; /** Path to the directory */
nsString mSubstName; /** Name to substitute with */
};
public:
explicit TelemetryIOInterposeObserver(nsIFile* aXreDir);
/**
* An implementation of Observe that records statistics of all
* file IO operations.
*/
void Observe(Observation& aOb) override;
/**
* Reflect recorded file IO statistics into Javascript
*/
bool ReflectIntoJS(JSContext* cx, JS::Handle<JSObject*> rootObj);
/**
* Adds a path for inclusion in main thread I/O report.
* @param aPath Directory path
* @param aSubstName Name to substitute for aPath for privacy reasons
*/
void AddPath(const nsAString& aPath, const nsAString& aSubstName);
/**
* Get size of hash table with file stats
*/
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
enum Stage { STAGE_STARTUP = 0, STAGE_NORMAL, STAGE_SHUTDOWN, NUM_STAGES };
static inline Stage NextStage(Stage aStage) {
switch (aStage) {
case STAGE_STARTUP:
return STAGE_NORMAL;
case STAGE_NORMAL:
return STAGE_SHUTDOWN;
case STAGE_SHUTDOWN:
return STAGE_SHUTDOWN;
default:
return NUM_STAGES;
}
}
struct FileStatsByStage {
FileStats mStats[NUM_STAGES];
};
typedef nsBaseHashtableET<nsStringHashKey, FileStatsByStage> FileIOEntryType;
// Statistics for each filename
Common::AutoHashtable<FileIOEntryType> mFileStats;
// Container for allowed directories
nsTArray<SafeDir> mSafeDirs;
Stage mCurStage;
/**
* Reflect a FileIOEntryType object to a Javascript property on obj with
* filename as key containing array:
* [totalTime, creates, reads, writes, fsyncs, stats]
*/
static bool ReflectFileStats(FileIOEntryType* entry, JSContext* cx,
JS::Handle<JSObject*> obj);
};
} // namespace Telemetry
} // namespace mozilla
#endif // TelemetryIOInterposeObserver_h__
|