summaryrefslogtreecommitdiffstats
path: root/js/src/wasm/WasmDebug.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/wasm/WasmDebug.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/js/src/wasm/WasmDebug.h b/js/src/wasm/WasmDebug.h
new file mode 100644
index 0000000000..21813ac1e6
--- /dev/null
+++ b/js/src/wasm/WasmDebug.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ *
+ * Copyright 2016 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_debug_h
+#define wasm_debug_h
+
+#include "js/HashTable.h"
+#include "wasm/WasmModule.h"
+#include "wasm/WasmTypes.h"
+
+namespace js {
+
+class Debugger;
+class WasmBreakpointSite;
+class WasmInstanceObject;
+
+namespace wasm {
+
+struct MetadataTier;
+
+// The generated source location for the AST node/expression. The offset field
+// refers an offset in an binary format file.
+
+struct ExprLoc {
+ uint32_t lineno;
+ uint32_t column;
+ uint32_t offset;
+ ExprLoc() : lineno(0), column(0), offset(0) {}
+ ExprLoc(uint32_t lineno_, uint32_t column_, uint32_t offset_)
+ : lineno(lineno_), column(column_), offset(offset_) {}
+};
+
+typedef HashMap<uint32_t, uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy>
+ StepperCounters;
+typedef HashMap<uint32_t, WasmBreakpointSite*, DefaultHasher<uint32_t>,
+ SystemAllocPolicy>
+ WasmBreakpointSiteMap;
+
+class DebugState {
+ const SharedCode code_;
+ const SharedModule module_;
+
+ // State maintained when debugging is enabled. In this case, the Code is
+ // not actually shared, but is referenced uniquely by the instance that is
+ // being debugged.
+
+ bool enterFrameTrapsEnabled_;
+ uint32_t enterAndLeaveFrameTrapsCounter_;
+ WasmBreakpointSiteMap breakpointSites_;
+ StepperCounters stepperCounters_;
+
+ void toggleDebugTrap(uint32_t offset, bool enabled);
+
+ public:
+ DebugState(const Code& code, const Module& module);
+
+ void trace(JSTracer* trc);
+ void finalize(JSFreeOp* fop);
+
+ const Bytes& bytecode() const { return module_->debugBytecode(); }
+
+ [[nodiscard]] bool getLineOffsets(size_t lineno, Vector<uint32_t>* offsets);
+ [[nodiscard]] bool getAllColumnOffsets(Vector<ExprLoc>* offsets);
+ [[nodiscard]] bool getOffsetLocation(uint32_t offset, size_t* lineno,
+ size_t* column);
+
+ // The Code can track enter/leave frame events. Any such event triggers
+ // debug trap. The enter/leave frame events enabled or disabled across
+ // all functions.
+
+ void adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled);
+ void ensureEnterFrameTrapsState(JSContext* cx, bool enabled);
+ bool enterFrameTrapsEnabled() const { return enterFrameTrapsEnabled_; }
+
+ // When the Code is debugEnabled, individual breakpoints can be enabled or
+ // disabled at instruction offsets.
+
+ bool hasBreakpointTrapAtOffset(uint32_t offset);
+ void toggleBreakpointTrap(JSRuntime* rt, uint32_t offset, bool enabled);
+ WasmBreakpointSite* getBreakpointSite(uint32_t offset) const;
+ WasmBreakpointSite* getOrCreateBreakpointSite(JSContext* cx,
+ Instance* instance,
+ uint32_t offset);
+ bool hasBreakpointSite(uint32_t offset);
+ void destroyBreakpointSite(JSFreeOp* fop, Instance* instance,
+ uint32_t offset);
+ void clearBreakpointsIn(JSFreeOp* fp, WasmInstanceObject* instance,
+ js::Debugger* dbg, JSObject* handler);
+
+ // When the Code is debug-enabled, single-stepping mode can be toggled on
+ // the granularity of individual functions.
+
+ bool stepModeEnabled(uint32_t funcIndex) const;
+ [[nodiscard]] bool incrementStepperCount(JSContext* cx, uint32_t funcIndex);
+ void decrementStepperCount(JSFreeOp* fop, uint32_t funcIndex);
+
+ // Stack inspection helpers.
+
+ [[nodiscard]] bool debugGetLocalTypes(uint32_t funcIndex,
+ ValTypeVector* locals,
+ size_t* argsLength,
+ StackResults* stackResults);
+ // Invariant: the result of getDebugResultType can only be used as long as
+ // code_->metadata() is live. See MetaData::getFuncResultType for more
+ // information.
+ ResultType debugGetResultType(uint32_t funcIndex) const {
+ return metadata().getFuncResultType(funcIndex);
+ }
+ [[nodiscard]] bool getGlobal(Instance& instance, uint32_t globalIndex,
+ MutableHandleValue vp);
+
+ // Debug URL helpers.
+
+ [[nodiscard]] bool getSourceMappingURL(JSContext* cx,
+ MutableHandleString result) const;
+
+ // Accessors for commonly used elements of linked structures.
+
+ const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
+ const Metadata& metadata() const { return code_->metadata(); }
+ const CodeRangeVector& codeRanges(Tier t) const {
+ return metadata(t).codeRanges;
+ }
+ const CallSiteVector& callSites(Tier t) const {
+ return metadata(t).callSites;
+ }
+
+ uint32_t funcToCodeRangeIndex(uint32_t funcIndex) const {
+ return metadata(Tier::Debug).funcToCodeRange[funcIndex];
+ }
+
+ // about:memory reporting:
+
+ void addSizeOfMisc(MallocSizeOf mallocSizeOf, Metadata::SeenSet* seenMetadata,
+ Code::SeenSet* seenCode, size_t* code, size_t* data) const;
+};
+
+using UniqueDebugState = UniquePtr<DebugState>;
+
+} // namespace wasm
+} // namespace js
+
+#endif // wasm_debug_h