Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : *
4 : * Copyright 2016 Mozilla Foundation
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : #ifndef wasm_debug_h
20 : #define wasm_debug_h
21 :
22 : #include "js/HashTable.h"
23 : #include "wasm/WasmCode.h"
24 : #include "wasm/WasmTypes.h"
25 :
26 : namespace js {
27 :
28 : class Debugger;
29 : class WasmActivation;
30 : class WasmBreakpoint;
31 : class WasmBreakpointSite;
32 : class WasmInstanceObject;
33 :
34 : namespace wasm {
35 :
36 : struct LinkData;
37 : struct LinkDataTier;
38 : struct MetadataTier;
39 : class FrameIterator;
40 :
41 : // The generated source location for the AST node/expression. The offset field refers
42 : // an offset in an binary format file.
43 :
44 : struct ExprLoc
45 : {
46 : uint32_t lineno;
47 : uint32_t column;
48 : uint32_t offset;
49 : ExprLoc() : lineno(0), column(0), offset(0) {}
50 0 : ExprLoc(uint32_t lineno_, uint32_t column_, uint32_t offset_)
51 0 : : lineno(lineno_), column(column_), offset(offset_)
52 0 : {}
53 : };
54 :
55 : typedef Vector<ExprLoc, 0, SystemAllocPolicy> ExprLocVector;
56 : typedef Vector<uint32_t, 0, SystemAllocPolicy> ExprLocIndexVector;
57 :
58 : // The generated source map for WebAssembly binary file. This map is generated during
59 : // building the text buffer (see BinaryToExperimentalText).
60 :
61 0 : class GeneratedSourceMap
62 : {
63 : ExprLocVector exprlocs_;
64 : UniquePtr<ExprLocIndexVector> sortedByOffsetExprLocIndices_;
65 : uint32_t totalLines_;
66 :
67 : public:
68 0 : explicit GeneratedSourceMap() : totalLines_(0) {}
69 0 : ExprLocVector& exprlocs() { return exprlocs_; }
70 :
71 0 : uint32_t totalLines() { return totalLines_; }
72 : void setTotalLines(uint32_t val) { totalLines_ = val; }
73 :
74 : bool searchLineByOffset(JSContext* cx, uint32_t offset, size_t* exprlocIndex);
75 :
76 : size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
77 : };
78 :
79 : typedef UniquePtr<GeneratedSourceMap> UniqueGeneratedSourceMap;
80 : typedef HashMap<uint32_t, uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy> StepModeCounters;
81 : typedef HashMap<uint32_t, WasmBreakpointSite*, DefaultHasher<uint32_t>, SystemAllocPolicy> WasmBreakpointSiteMap;
82 :
83 0 : class DebugState
84 : {
85 : const SharedCode code_;
86 : const SharedBytes maybeBytecode_;
87 : UniqueGeneratedSourceMap maybeSourceMap_;
88 : bool binarySource_;
89 :
90 : // State maintained when debugging is enabled. In this case, the Code is
91 : // not actually shared, but is referenced uniquely by the instance that is
92 : // being debugged.
93 :
94 : uint32_t enterAndLeaveFrameTrapsCounter_;
95 : WasmBreakpointSiteMap breakpointSites_;
96 : StepModeCounters stepModeCounters_;
97 :
98 : void toggleDebugTrap(uint32_t offset, bool enabled);
99 : bool ensureSourceMap(JSContext* cx);
100 :
101 : public:
102 : DebugState(SharedCode code,
103 : const ShareableBytes* maybeBytecode,
104 : bool binarySource);
105 :
106 0 : const Bytes* maybeBytecode() const { return maybeBytecode_ ? &maybeBytecode_->bytes : nullptr; }
107 0 : bool binarySource() const { return binarySource_; }
108 :
109 : // If the source bytecode was saved when this Code was constructed, this
110 : // method will render the binary as text. Otherwise, a diagnostic string
111 : // will be returned.
112 :
113 : JSString* createText(JSContext* cx);
114 : bool getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offsets);
115 : bool getAllColumnOffsets(JSContext* cx, Vector<ExprLoc>* offsets);
116 : bool getOffsetLocation(JSContext* cx, uint32_t offset, bool* found, size_t* lineno, size_t* column);
117 : bool totalSourceLines(JSContext* cx, uint32_t* count);
118 :
119 : // The Code can track enter/leave frame events. Any such event triggers
120 : // debug trap. The enter/leave frame events enabled or disabled across
121 : // all functions.
122 :
123 : void adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled);
124 :
125 : // When the Code is debugEnabled, individual breakpoints can be enabled or
126 : // disabled at instruction offsets.
127 :
128 : bool hasBreakpointTrapAtOffset(uint32_t offset);
129 : void toggleBreakpointTrap(JSRuntime* rt, uint32_t offset, bool enabled);
130 : WasmBreakpointSite* getOrCreateBreakpointSite(JSContext* cx, uint32_t offset);
131 : bool hasBreakpointSite(uint32_t offset);
132 : void destroyBreakpointSite(FreeOp* fop, uint32_t offset);
133 : bool clearBreakpointsIn(JSContext* cx, WasmInstanceObject* instance, js::Debugger* dbg, JSObject* handler);
134 :
135 : // When the Code is debug-enabled, single-stepping mode can be toggled on
136 : // the granularity of individual functions.
137 :
138 : bool stepModeEnabled(uint32_t funcIndex) const;
139 : bool incrementStepModeCount(JSContext* cx, uint32_t funcIndex);
140 : bool decrementStepModeCount(FreeOp* fop, uint32_t funcIndex);
141 :
142 : // Stack inspection helpers.
143 :
144 : bool debugGetLocalTypes(uint32_t funcIndex, ValTypeVector* locals, size_t* argsLength);
145 : ExprType debugGetResultType(uint32_t funcIndex);
146 :
147 : // Debug URL helpers.
148 :
149 : JSString* debugDisplayURL(JSContext* cx) const;
150 : bool getSourceMappingURL(JSContext* cx, MutableHandleString result) const;
151 :
152 : // Accessors for commonly used elements of linked structures.
153 :
154 0 : const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
155 0 : const Metadata& metadata() const { return code_->metadata(); }
156 0 : bool debugEnabled() const { return metadata().debugEnabled; }
157 0 : const CodeRangeVector& codeRanges(Tier t) const { return metadata(t).codeRanges; }
158 0 : const CallSiteVector& callSites(Tier t) const { return metadata(t).callSites; }
159 :
160 0 : uint32_t debugFuncToCodeRangeIndex(uint32_t funcIndex) const {
161 0 : return metadata(Tier::Debug).debugFuncToCodeRange[funcIndex];
162 : }
163 :
164 : // about:memory reporting:
165 :
166 : void addSizeOfMisc(MallocSizeOf mallocSizeOf,
167 : Metadata::SeenSet* seenMetadata,
168 : ShareableBytes::SeenSet* seenBytes,
169 : Code::SeenSet* seenCode,
170 : size_t* code,
171 : size_t* data) const;
172 : };
173 :
174 : typedef UniquePtr<DebugState> UniqueDebugState;
175 :
176 : } // namespace wasm
177 : } // namespace js
178 :
179 : #endif // wasm_debug_h
|