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_instance_h
20 : #define wasm_instance_h
21 :
22 : #include "gc/Barrier.h"
23 : #include "wasm/WasmCode.h"
24 : #include "wasm/WasmDebug.h"
25 : #include "wasm/WasmTable.h"
26 :
27 : namespace js {
28 : namespace wasm {
29 :
30 : // A wasm GlobalSegment owns the allocated global data for a wasm module. A
31 : // module may be compiled multiple times (at multiple tiers) but the compiled
32 : // representations share the same GlobalSegment.
33 :
34 : class GlobalSegment
35 : {
36 : uint32_t globalDataLength_;
37 : TlsData* tlsData_;
38 :
39 : GlobalSegment(const GlobalSegment&) = delete;
40 : GlobalSegment(GlobalSegment&&) = delete;
41 : void operator=(const GlobalSegment&) = delete;
42 : void operator=(GlobalSegment&&) = delete;
43 :
44 : public:
45 : static UniquePtr<GlobalSegment> create(uint32_t globalDataLength);
46 :
47 0 : GlobalSegment() { PodZero(this); }
48 : ~GlobalSegment();
49 :
50 0 : TlsData* tlsData() const { return tlsData_; }
51 0 : uint8_t* globalData() const { return (uint8_t*)&tlsData_->globalArea; }
52 : uint32_t globalDataLength() const { return globalDataLength_; }
53 :
54 : size_t sizeOfMisc(MallocSizeOf mallocSizeOf) const;
55 : };
56 :
57 : typedef UniquePtr<GlobalSegment> UniqueGlobalSegment;
58 :
59 : // Instance represents a wasm instance and provides all the support for runtime
60 : // execution of code in the instance. Instances share various immutable data
61 : // structures with the Module from which they were instantiated and other
62 : // instances instantiated from the same Module. However, an Instance has no
63 : // direct reference to its source Module which allows a Module to be destroyed
64 : // while it still has live Instances.
65 : //
66 : // The instance's code may be shared among multiple instances provided none of
67 : // those instances are being debugged. Instances that are being debugged own
68 : // their code.
69 :
70 : class Instance
71 : {
72 : JSCompartment* const compartment_;
73 : ReadBarrieredWasmInstanceObject object_;
74 : const SharedCode code_;
75 : const UniqueDebugState debug_;
76 : const UniqueGlobalSegment globals_;
77 : GCPtrWasmMemoryObject memory_;
78 : SharedTableVector tables_;
79 : bool enterFrameTrapsEnabled_;
80 :
81 : // Internal helpers:
82 : const void** addressOfSigId(const SigIdDesc& sigId) const;
83 : FuncImportTls& funcImportTls(const FuncImport& fi);
84 : TableTls& tableTls(const TableDesc& td) const;
85 :
86 : // Only WasmInstanceObject can call the private trace function.
87 : friend class js::WasmInstanceObject;
88 : void tracePrivate(JSTracer* trc);
89 :
90 : bool callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, const uint64_t* argv,
91 : MutableHandleValue rval);
92 :
93 : public:
94 : Instance(JSContext* cx,
95 : HandleWasmInstanceObject object,
96 : SharedCode code,
97 : UniqueDebugState debug,
98 : UniqueGlobalSegment globals,
99 : HandleWasmMemoryObject memory,
100 : SharedTableVector&& tables,
101 : Handle<FunctionVector> funcImports,
102 : const ValVector& globalImports);
103 : ~Instance();
104 : bool init(JSContext* cx);
105 : void trace(JSTracer* trc);
106 :
107 0 : JSCompartment* compartment() const { return compartment_; }
108 0 : const Code& code() const { return *code_; }
109 0 : DebugState& debug() { return *debug_; }
110 : const DebugState& debug() const { return *debug_; }
111 0 : const CodeSegment& codeSegment(Tier t) const { return code_->segment(t); }
112 0 : const GlobalSegment& globalSegment() const { return *globals_; }
113 0 : uint8_t* codeBase(Tier t) const { return code_->segment(t).base(); }
114 0 : const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
115 0 : const Metadata& metadata() const { return code_->metadata(); }
116 0 : bool isAsmJS() const { return metadata().isAsmJS(); }
117 0 : const SharedTableVector& tables() const { return tables_; }
118 : SharedMem<uint8_t*> memoryBase() const;
119 : size_t memoryLength() const;
120 : size_t memoryMappedSize() const;
121 : bool memoryAccessInGuardRegion(uint8_t* addr, unsigned numBytes) const;
122 0 : TlsData* tlsData() const { return globals_->tlsData(); }
123 :
124 : // This method returns a pointer to the GC object that owns this Instance.
125 : // Instances may be reached via weak edges (e.g., Compartment::instances_)
126 : // so this perform a read-barrier on the returned object unless the barrier
127 : // is explicitly waived.
128 :
129 : WasmInstanceObject* object() const;
130 : WasmInstanceObject* objectUnbarriered() const;
131 :
132 : // Execute the given export given the JS call arguments, storing the return
133 : // value in args.rval.
134 :
135 : MOZ_MUST_USE bool callExport(JSContext* cx, uint32_t funcIndex, CallArgs args);
136 :
137 : // Return the name associated with a given function index, or generate one
138 : // if none was given by the module.
139 :
140 : bool getFuncName(uint32_t funcIndex, UTF8Bytes* name) const;
141 : JSAtom* getFuncAtom(JSContext* cx, uint32_t funcIndex) const;
142 : void ensureProfilingLabels(bool profilingEnabled) const;
143 :
144 : // Initially, calls to imports in wasm code call out through the generic
145 : // callImport method. If the imported callee gets JIT compiled and the types
146 : // match up, callImport will patch the code to instead call through a thunk
147 : // directly into the JIT code. If the JIT code is released, the Instance must
148 : // be notified so it can go back to the generic callImport.
149 :
150 : void deoptimizeImportExit(uint32_t funcImportIndex);
151 :
152 : // Called by simulators to check whether accessing 'numBytes' starting at
153 : // 'addr' would trigger a fault and be safely handled by signal handlers.
154 :
155 : bool memoryAccessWouldFault(uint8_t* addr, unsigned numBytes);
156 :
157 : // Called by Wasm(Memory|Table)Object when a moving resize occurs:
158 :
159 : void onMovingGrowMemory(uint8_t* prevMemoryBase);
160 : void onMovingGrowTable();
161 :
162 : // Debug support:
163 :
164 0 : bool debugEnabled() const { return metadata().debugEnabled; }
165 0 : bool enterFrameTrapsEnabled() const { return enterFrameTrapsEnabled_; }
166 : void ensureEnterFrameTrapsState(JSContext* cx, bool enabled);
167 :
168 : // about:memory reporting:
169 :
170 : void addSizeOfMisc(MallocSizeOf mallocSizeOf,
171 : Metadata::SeenSet* seenMetadata,
172 : ShareableBytes::SeenSet* seenBytes,
173 : Code::SeenSet* seenCode,
174 : Table::SeenSet* seenTables,
175 : size_t* code,
176 : size_t* data) const;
177 :
178 : public:
179 : // Functions to be called directly from wasm code.
180 : static int32_t callImport_void(Instance*, int32_t, int32_t, uint64_t*);
181 : static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*);
182 : static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*);
183 : static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*);
184 : static uint32_t growMemory_i32(Instance* instance, uint32_t delta);
185 : static uint32_t currentMemory_i32(Instance* instance);
186 : };
187 :
188 : typedef UniquePtr<Instance> UniqueInstance;
189 :
190 : bool InitInstanceStaticData();
191 : void ShutDownInstanceStaticData();
192 :
193 : } // namespace wasm
194 : } // namespace js
195 :
196 : #endif // wasm_instance_h
|