OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_WASM_OBJECTS_H_ | 5 #ifndef V8_WASM_OBJECTS_H_ |
6 #define V8_WASM_OBJECTS_H_ | 6 #define V8_WASM_OBJECTS_H_ |
7 | 7 |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/debug/interface-types.h" | 9 #include "src/debug/interface-types.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 #include "src/objects/script.h" | 11 #include "src/objects/script.h" |
12 #include "src/trap-handler/trap-handler.h" | 12 #include "src/trap-handler/trap-handler.h" |
13 #include "src/wasm/wasm-limits.h" | 13 #include "src/wasm/wasm-limits.h" |
14 #include "src/wasm/wasm-module.h" | 14 #include "src/wasm/wasm-module.h" |
15 | 15 |
| 16 #include "src/heap/heap-inl.h" |
| 17 #include "src/heap/heap.h" |
| 18 |
| 19 // Has to be the last include (doesn't have include guards) |
| 20 #include "src/objects/object-macros.h" |
| 21 |
16 namespace v8 { | 22 namespace v8 { |
17 namespace internal { | 23 namespace internal { |
18 namespace wasm { | 24 namespace wasm { |
19 class InterpretedFrame; | 25 class InterpretedFrame; |
20 class WasmInterpreter; | 26 class WasmInterpreter; |
21 } | 27 } |
22 | 28 |
23 class WasmCompiledModule; | 29 class WasmCompiledModule; |
24 class WasmDebugInfo; | 30 class WasmDebugInfo; |
25 class WasmInstanceObject; | 31 class WasmInstanceObject; |
26 class WasmInstanceWrapper; | 32 class WasmInstanceWrapper; |
27 | 33 |
28 #define DECLARE_CASTS(name) \ | 34 #define DECL_OOL_QUERY(type) static bool Is##type(Object* object); |
29 static bool Is##name(Object* object); \ | 35 #define DECL_OOL_CAST(type) static type* cast(Object* object); |
30 static name* cast(Object* object) | |
31 | 36 |
32 #define DECLARE_GETTER(name, type) type* name() | 37 #define DECL_GETTER(name, type) type* name(); |
33 | 38 |
34 #define DECLARE_ACCESSORS(name, type) \ | 39 #define DECL_OPTIONAL_ACCESSORS(name, type) \ |
35 void set_##name(type* value); \ | 40 INLINE(bool has_##name()); \ |
36 DECLARE_GETTER(name, type) | 41 DECL_ACCESSORS(name, type) |
37 | 42 |
38 #define DECLARE_OPTIONAL_ACCESSORS(name, type) \ | 43 #define DECL_OPTIONAL_GETTER(name, type) \ |
39 bool has_##name(); \ | 44 INLINE(bool has_##name()); \ |
40 DECLARE_ACCESSORS(name, type) | 45 DECL_GETTER(name, type) |
41 | 46 |
42 #define DECLARE_OPTIONAL_GETTER(name, type) \ | 47 #define DEF_SIZE(parent) \ |
43 bool has_##name(); \ | 48 static const int kSize = parent::kHeaderSize + kFieldCount * kPointerSize; \ |
44 DECLARE_GETTER(name, type) | 49 static const int kParentSize = parent::kHeaderSize; \ |
| 50 static const int kHeaderSize = kSize; |
| 51 #define DEF_OFFSET(name) \ |
| 52 static const int k##name##Offset = \ |
| 53 kSize + (k##name##Index - kFieldCount) * kPointerSize; |
45 | 54 |
46 // Representation of a WebAssembly.Module JavaScript-level object. | 55 // Representation of a WebAssembly.Module JavaScript-level object. |
47 class WasmModuleObject : public JSObject { | 56 class WasmModuleObject : public JSObject { |
48 public: | 57 public: |
49 // If a second field is added, we need a kWrapperTracerHeader field as well. | 58 DECL_CAST(WasmModuleObject) |
50 // TODO(titzer): add the brand as an embedder field instead of a property. | |
51 enum Fields { kCompiledModule, kFieldCount }; | |
52 | 59 |
53 DECLARE_CASTS(WasmModuleObject); | 60 // Shared compiled code between multiple WebAssembly.Module objects. |
| 61 DECL_ACCESSORS(compiled_module, WasmCompiledModule) |
54 | 62 |
55 WasmCompiledModule* compiled_module(); | 63 enum { // -- |
| 64 kCompiledModuleIndex, |
| 65 kFieldCount |
| 66 }; |
| 67 |
| 68 DEF_SIZE(JSObject) |
| 69 DEF_OFFSET(CompiledModule) |
56 | 70 |
57 static Handle<WasmModuleObject> New( | 71 static Handle<WasmModuleObject> New( |
58 Isolate* isolate, Handle<WasmCompiledModule> compiled_module); | 72 Isolate* isolate, Handle<WasmCompiledModule> compiled_module); |
59 }; | 73 }; |
60 | 74 |
61 // Representation of a WebAssembly.Table JavaScript-level object. | 75 // Representation of a WebAssembly.Table JavaScript-level object. |
62 class WasmTableObject : public JSObject { | 76 class WasmTableObject : public JSObject { |
63 public: | 77 public: |
64 // The 0-th field is used by the Blink Wrapper Tracer. | 78 DECL_CAST(WasmTableObject) |
65 // TODO(titzer): add the brand as an embedder field instead of a property. | 79 |
66 enum Fields { | 80 DECL_ACCESSORS(functions, FixedArray) |
67 kWrapperTracerHeader, | 81 DECL_INT_ACCESSORS(maximum_length) |
68 kFunctions, | 82 DECL_ACCESSORS(dispatch_tables, FixedArray) |
69 kMaximum, | 83 |
70 kDispatchTables, | 84 enum { // -- |
| 85 kFunctionsIndex, |
| 86 kMaximumLengthIndex, |
| 87 kDispatchTablesIndex, |
71 kFieldCount | 88 kFieldCount |
72 }; | 89 }; |
73 | 90 |
74 DECLARE_CASTS(WasmTableObject); | 91 DEF_SIZE(JSObject) |
75 DECLARE_ACCESSORS(functions, FixedArray); | 92 DEF_OFFSET(Functions) |
76 DECLARE_GETTER(dispatch_tables, FixedArray); | 93 DEF_OFFSET(MaximumLength) |
| 94 DEF_OFFSET(DispatchTables) |
77 | 95 |
78 uint32_t current_length(); | 96 inline uint32_t current_length() { return functions()->length(); } |
79 bool has_maximum_length(); | 97 inline bool has_maximum_length() { return maximum_length() >= 0; } |
80 int64_t maximum_length(); // Returns < 0 if no maximum. | |
81 void grow(Isolate* isolate, uint32_t count); | 98 void grow(Isolate* isolate, uint32_t count); |
82 | 99 |
83 static Handle<WasmTableObject> New(Isolate* isolate, uint32_t initial, | 100 static Handle<WasmTableObject> New(Isolate* isolate, uint32_t initial, |
84 int64_t maximum, | 101 int64_t maximum, |
85 Handle<FixedArray>* js_functions); | 102 Handle<FixedArray>* js_functions); |
86 static Handle<FixedArray> AddDispatchTable( | 103 static Handle<FixedArray> AddDispatchTable( |
87 Isolate* isolate, Handle<WasmTableObject> table, | 104 Isolate* isolate, Handle<WasmTableObject> table, |
88 Handle<WasmInstanceObject> instance, int table_index, | 105 Handle<WasmInstanceObject> instance, int table_index, |
89 Handle<FixedArray> function_table, Handle<FixedArray> signature_table); | 106 Handle<FixedArray> function_table, Handle<FixedArray> signature_table); |
90 }; | 107 }; |
91 | 108 |
92 // Representation of a WebAssembly.Memory JavaScript-level object. | 109 // Representation of a WebAssembly.Memory JavaScript-level object. |
93 class WasmMemoryObject : public JSObject { | 110 class WasmMemoryObject : public JSObject { |
94 public: | 111 public: |
95 // The 0-th field is used by the Blink Wrapper Tracer. | 112 DECL_CAST(WasmMemoryObject) |
96 // TODO(titzer): add the brand as an embedder field instead of a property. | 113 |
97 enum Fields : uint8_t { | 114 DECL_ACCESSORS(array_buffer, JSArrayBuffer) |
98 kWrapperTracerHeader, | 115 DECL_INT_ACCESSORS(maximum_pages) |
99 kArrayBuffer, | 116 DECL_OPTIONAL_ACCESSORS(instances_link, WasmInstanceWrapper) |
100 kMaximum, | 117 |
101 kInstancesLink, | 118 enum { // -- |
| 119 kArrayBufferIndex, |
| 120 kMaximumPagesIndex, |
| 121 kInstancesLinkIndex, |
102 kFieldCount | 122 kFieldCount |
103 }; | 123 }; |
104 | 124 |
105 DECLARE_CASTS(WasmMemoryObject); | 125 DEF_SIZE(JSObject) |
106 DECLARE_ACCESSORS(buffer, JSArrayBuffer); | 126 DEF_OFFSET(ArrayBuffer) |
107 DECLARE_OPTIONAL_ACCESSORS(instances_link, WasmInstanceWrapper); | 127 DEF_OFFSET(MaximumPages) |
| 128 DEF_OFFSET(InstancesLink) |
108 | 129 |
109 void AddInstance(Isolate* isolate, Handle<WasmInstanceObject> object); | 130 void AddInstance(Isolate* isolate, Handle<WasmInstanceObject> object); |
110 void ResetInstancesLink(Isolate* isolate); | 131 inline void ResetInstancesLink(Isolate* isolate); |
111 uint32_t current_pages(); | 132 uint32_t current_pages(); |
112 bool has_maximum_pages(); | 133 inline bool has_maximum_pages() { return maximum_pages() >= 0; } |
113 int32_t maximum_pages(); // Returns < 0 if there is no maximum. | |
114 | 134 |
115 static Handle<WasmMemoryObject> New(Isolate* isolate, | 135 static Handle<WasmMemoryObject> New(Isolate* isolate, |
116 Handle<JSArrayBuffer> buffer, | 136 Handle<JSArrayBuffer> buffer, |
117 int32_t maximum); | 137 int32_t maximum); |
118 | 138 |
119 static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, uint32_t pages); | 139 static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, uint32_t pages); |
120 }; | 140 }; |
121 | 141 |
122 // Representation of a WebAssembly.Instance JavaScript-level object. | 142 // A WebAssembly.Instance JavaScript-level object. |
123 class WasmInstanceObject : public JSObject { | 143 class WasmInstanceObject : public JSObject { |
124 public: | 144 public: |
125 // The 0-th field is used by the Blink Wrapper Tracer. | 145 DECL_CAST(WasmInstanceObject) |
126 // TODO(titzer): add the brand as an embedder field instead of a property. | 146 |
127 enum Fields { | 147 DECL_ACCESSORS(compiled_module, WasmCompiledModule) |
128 kWrapperTracerHeader, | 148 DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject) |
129 kCompiledModule, | 149 DECL_OPTIONAL_ACCESSORS(memory_buffer, JSArrayBuffer) |
130 kMemoryObject, | 150 DECL_OPTIONAL_ACCESSORS(globals_buffer, JSArrayBuffer) |
131 kMemoryArrayBuffer, | 151 DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo) |
132 kGlobalsArrayBuffer, | 152 DECL_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper) |
133 kDebugInfo, | 153 // FixedArray of all instances whose code was imported |
134 kWasmMemInstanceWrapper, | 154 DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray) |
135 // FixedArray of wasm instances whose code we imported (to keep them alive). | 155 |
136 kDirectlyCalledInstances, | 156 enum { // -- |
| 157 kCompiledModuleIndex, |
| 158 kMemoryObjectIndex, |
| 159 kMemoryBufferIndex, |
| 160 kGlobalsBufferIndex, |
| 161 kDebugInfoIndex, |
| 162 kInstanceWrapperIndex, |
| 163 kDirectlyCalledInstancesIndex, |
137 kFieldCount | 164 kFieldCount |
138 }; | 165 }; |
139 | 166 |
140 DECLARE_CASTS(WasmInstanceObject); | 167 DEF_SIZE(JSObject) |
141 | 168 DEF_OFFSET(CompiledModule) |
142 DECLARE_ACCESSORS(compiled_module, WasmCompiledModule); | 169 DEF_OFFSET(MemoryObject) |
143 DECLARE_OPTIONAL_ACCESSORS(globals_buffer, JSArrayBuffer); | 170 DEF_OFFSET(MemoryBuffer) |
144 DECLARE_OPTIONAL_ACCESSORS(memory_buffer, JSArrayBuffer); | 171 DEF_OFFSET(GlobalsBuffer) |
145 DECLARE_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject); | 172 DEF_OFFSET(DebugInfo) |
146 DECLARE_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo); | 173 DEF_OFFSET(InstanceWrapper) |
147 DECLARE_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper); | 174 DEF_OFFSET(DirectlyCalledInstances) |
148 DECLARE_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray); | |
149 | 175 |
150 WasmModuleObject* module_object(); | 176 WasmModuleObject* module_object(); |
151 V8_EXPORT_PRIVATE wasm::WasmModule* module(); | 177 V8_EXPORT_PRIVATE wasm::WasmModule* module(); |
152 | 178 |
153 // Get the debug info associated with the given wasm object. | 179 // Get the debug info associated with the given wasm object. |
154 // If no debug info exists yet, it is created automatically. | 180 // If no debug info exists yet, it is created automatically. |
155 static Handle<WasmDebugInfo> GetOrCreateDebugInfo(Handle<WasmInstanceObject>); | 181 static Handle<WasmDebugInfo> GetOrCreateDebugInfo(Handle<WasmInstanceObject>); |
156 | 182 |
157 static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmCompiledModule>); | 183 static Handle<WasmInstanceObject> New(Isolate*, Handle<WasmCompiledModule>); |
158 | 184 |
159 int32_t GetMemorySize(); | 185 int32_t GetMemorySize(); |
160 | 186 |
161 static int32_t GrowMemory(Isolate*, Handle<WasmInstanceObject>, | 187 static int32_t GrowMemory(Isolate*, Handle<WasmInstanceObject>, |
162 uint32_t pages); | 188 uint32_t pages); |
163 | 189 |
164 uint32_t GetMaxMemoryPages(); | 190 uint32_t GetMaxMemoryPages(); |
165 }; | 191 }; |
166 | 192 |
167 // Representation of an exported wasm function. | 193 // A WASM function that is wrapped and exported to JavaScript. |
168 class WasmExportedFunction : public JSFunction { | 194 class WasmExportedFunction : public JSFunction { |
169 public: | 195 public: |
170 // The 0-th field is used by the Blink Wrapper Tracer. | 196 DECL_OOL_QUERY(WasmExportedFunction) |
171 enum Fields { kWrapperTracerHeader, kInstance, kIndex, kFieldCount }; | 197 DECL_OOL_CAST(WasmExportedFunction) |
172 | 198 |
173 DECLARE_CASTS(WasmExportedFunction); | 199 DECL_ACCESSORS(instance, WasmInstanceObject) |
| 200 DECL_INT_ACCESSORS(function_index) |
174 | 201 |
175 WasmInstanceObject* instance(); | 202 enum { // -- |
176 int function_index(); | 203 kInstanceIndex, |
| 204 kFunctionIndexIndex, |
| 205 kFieldCount |
| 206 }; |
| 207 |
| 208 static const int kSize = JSFunction::kSize + kFieldCount * kPointerSize; |
| 209 DEF_OFFSET(Instance) |
| 210 DEF_OFFSET(FunctionIndex) |
177 | 211 |
178 static Handle<WasmExportedFunction> New(Isolate* isolate, | 212 static Handle<WasmExportedFunction> New(Isolate* isolate, |
179 Handle<WasmInstanceObject> instance, | 213 Handle<WasmInstanceObject> instance, |
180 MaybeHandle<String> maybe_name, | 214 MaybeHandle<String> maybe_name, |
181 int func_index, int arity, | 215 int func_index, int arity, |
182 Handle<Code> export_wrapper); | 216 Handle<Code> export_wrapper); |
183 }; | 217 }; |
184 | 218 |
185 // Information shared by all WasmCompiledModule objects for the same module. | 219 // Information shared by all WasmCompiledModule objects for the same module. |
186 class WasmSharedModuleData : public FixedArray { | 220 class WasmSharedModuleData : public FixedArray { |
187 // The 0-th field is used by the Blink Wrapper Tracer. | 221 public: |
188 enum Fields { | 222 DECL_OOL_QUERY(WasmSharedModuleData) |
189 kWrapperTracerHeader, | 223 DECL_OOL_CAST(WasmSharedModuleData) |
190 kModuleWrapper, | 224 |
191 kModuleBytes, | 225 DECL_GETTER(module, wasm::WasmModule) |
192 kScript, | 226 DECL_OPTIONAL_ACCESSORS(module_bytes, SeqOneByteString) |
193 kAsmJsOffsetTable, | 227 DECL_ACCESSORS(script, Script) |
194 kBreakPointInfos, | 228 DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray) |
195 kLazyCompilationOrchestrator, | 229 DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray) |
| 230 |
| 231 enum { // -- |
| 232 kModuleWrapperIndex, |
| 233 kModuleBytesIndex, |
| 234 kScriptIndex, |
| 235 kAsmJsOffsetTableIndex, |
| 236 kBreakPointInfosIndex, |
| 237 kLazyCompilationOrchestratorIndex, |
196 kFieldCount | 238 kFieldCount |
197 }; | 239 }; |
198 | 240 |
199 public: | 241 DEF_SIZE(FixedArray) |
200 DECLARE_CASTS(WasmSharedModuleData); | 242 DEF_OFFSET(ModuleWrapper) |
201 | 243 DEF_OFFSET(ModuleBytes) |
202 DECLARE_GETTER(module, wasm::WasmModule); | 244 DEF_OFFSET(Script) |
203 DECLARE_OPTIONAL_ACCESSORS(module_bytes, SeqOneByteString); | 245 DEF_OFFSET(AsmJsOffsetTable) |
204 DECLARE_GETTER(script, Script); | 246 DEF_OFFSET(BreakPointInfos) |
205 DECLARE_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray); | 247 DEF_OFFSET(LazyCompilationOrchestrator) |
206 DECLARE_OPTIONAL_GETTER(breakpoint_infos, FixedArray); | |
207 | |
208 static Handle<WasmSharedModuleData> New( | |
209 Isolate* isolate, Handle<Foreign> module_wrapper, | |
210 Handle<SeqOneByteString> module_bytes, Handle<Script> script, | |
211 Handle<ByteArray> asm_js_offset_table); | |
212 | 248 |
213 // Check whether this module was generated from asm.js source. | 249 // Check whether this module was generated from asm.js source. |
214 bool is_asm_js(); | 250 bool is_asm_js(); |
215 | 251 |
216 static void ReinitializeAfterDeserialization(Isolate*, | 252 static void ReinitializeAfterDeserialization(Isolate*, |
217 Handle<WasmSharedModuleData>); | 253 Handle<WasmSharedModuleData>); |
218 | 254 |
219 static void AddBreakpoint(Handle<WasmSharedModuleData>, int position, | 255 static void AddBreakpoint(Handle<WasmSharedModuleData>, int position, |
220 Handle<Object> break_point_object); | 256 Handle<Object> break_point_object); |
221 | 257 |
222 static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>, | 258 static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>, |
223 Handle<WasmInstanceObject>); | 259 Handle<WasmInstanceObject>); |
224 | 260 |
225 static void PrepareForLazyCompilation(Handle<WasmSharedModuleData>); | 261 static void PrepareForLazyCompilation(Handle<WasmSharedModuleData>); |
226 | 262 |
| 263 static Handle<WasmSharedModuleData> New( |
| 264 Isolate* isolate, Handle<Foreign> module_wrapper, |
| 265 Handle<SeqOneByteString> module_bytes, Handle<Script> script, |
| 266 Handle<ByteArray> asm_js_offset_table); |
| 267 |
227 private: | 268 private: |
228 DECLARE_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign); | 269 DECL_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign) |
229 friend class WasmCompiledModule; | 270 friend class WasmCompiledModule; |
230 }; | 271 }; |
231 | 272 |
232 // This represents the set of wasm compiled functions, together | 273 // This represents the set of wasm compiled functions, together |
233 // with all the information necessary for re-specializing them. | 274 // with all the information necessary for re-specializing them. |
234 // | 275 // |
235 // We specialize wasm functions to their instance by embedding: | 276 // We specialize wasm functions to their instance by embedding: |
236 // - raw interior pointers into the backing store of the array buffer | 277 // - raw interior pointers into the backing store of the array buffer |
237 // used as memory of a particular WebAssembly.Instance object. | 278 // used as memory of a particular WebAssembly.Instance object. |
238 // - bounds check limits, computed at compile time, relative to the | 279 // - bounds check limits, computed at compile time, relative to the |
239 // size of the memory. | 280 // size of the memory. |
240 // - the objects representing the function tables and signature tables | 281 // - the objects representing the function tables and signature tables |
241 // - raw pointer to the globals buffer. | 282 // - raw pointer to the globals buffer. |
242 // | 283 // |
243 // Even without instantiating, we need values for all of these parameters. | 284 // Even without instantiating, we need values for all of these parameters. |
244 // We need to track these values to be able to create new instances and | 285 // We need to track these values to be able to create new instances and |
245 // to be able to serialize/deserialize. | 286 // to be able to serialize/deserialize. |
246 // The design decisions for how we track these values is not too immediate, | 287 // The design decisions for how we track these values is not too immediate, |
247 // and it deserves a summary. The "tricky" ones are: memory, globals, and | 288 // and it deserves a summary. The "tricky" ones are: memory, globals, and |
248 // the tables (signature and functions). | 289 // the tables (signature and functions). |
249 // The first 2 (memory & globals) are embedded as raw pointers to native | 290 // The first 2 (memory & globals) are embedded as raw pointers to native |
250 // buffers. All we need to track them is the start addresses and, in the | 291 // buffers. All we need to track them is the start addresses and, in the |
251 // case of memory, the size. We model all of them as HeapNumbers, because | 292 // case of memory, the size. We model all of them as HeapNumbers, because |
252 // we need to store size_t values (for addresses), and potentially full | 293 // we need to store size_t values (for addresses), and potentially full |
253 // 32 bit unsigned values for the size. Smis are 31 bits. | 294 // 32 bit unsigned values for the size. Smis are 31 bits. |
254 // For tables, we need to hold a reference to the JS Heap object, because | 295 // For tables, we need to hold a reference to the JS Heap object, because |
255 // we embed them as objects, and they may move. | 296 // we embed them as objects, and they may move. |
256 class WasmCompiledModule : public FixedArray { | 297 class WasmCompiledModule : public FixedArray { |
257 public: | 298 public: |
258 enum Fields { kFieldCount }; | 299 enum { // -- |
| 300 kFieldCount |
| 301 }; |
259 | 302 |
260 static WasmCompiledModule* cast(Object* fixed_array) { | 303 static WasmCompiledModule* cast(Object* fixed_array) { |
261 SLOW_DCHECK(IsWasmCompiledModule(fixed_array)); | 304 SLOW_DCHECK(IsWasmCompiledModule(fixed_array)); |
262 return reinterpret_cast<WasmCompiledModule*>(fixed_array); | 305 return reinterpret_cast<WasmCompiledModule*>(fixed_array); |
263 } | 306 } |
264 | 307 |
265 #define WCM_OBJECT_OR_WEAK(TYPE, NAME, ID, TYPE_CHECK, SETTER_MODIFIER) \ | 308 #define WCM_OBJECT_OR_WEAK(TYPE, NAME, ID, TYPE_CHECK, SETTER_MODIFIER) \ |
266 public: \ | 309 public: \ |
267 Handle<TYPE> NAME() const { return handle(ptr_to_##NAME()); } \ | 310 Handle<TYPE> NAME() const { return handle(ptr_to_##NAME()); } \ |
268 \ | 311 \ |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 } | 580 } |
538 | 581 |
539 private: | 582 private: |
540 void InitId(); | 583 void InitId(); |
541 | 584 |
542 DISALLOW_IMPLICIT_CONSTRUCTORS(WasmCompiledModule); | 585 DISALLOW_IMPLICIT_CONSTRUCTORS(WasmCompiledModule); |
543 }; | 586 }; |
544 | 587 |
545 class WasmDebugInfo : public FixedArray { | 588 class WasmDebugInfo : public FixedArray { |
546 public: | 589 public: |
547 // The 0-th field is used by the Blink Wrapper Tracer. | 590 DECL_OOL_QUERY(WasmDebugInfo) |
548 enum Fields { | 591 DECL_OOL_CAST(WasmDebugInfo) |
549 kWrapperTracerHeader, | 592 |
550 kInstance, | 593 DECL_GETTER(wasm_instance, WasmInstanceObject) |
551 kInterpreterHandle, | 594 DECL_OPTIONAL_ACCESSORS(locals_names, FixedArray) |
552 kInterpretedFunctions, | 595 |
553 // FixedArray of FixedArray of <undefined|String>. | 596 enum { // -- |
554 kLocalsNames, | 597 kInstanceIndex, |
| 598 kInterpreterHandleIndex, |
| 599 kInterpretedFunctionsIndex, |
| 600 kLocalsNamesIndex, |
555 kFieldCount | 601 kFieldCount |
556 }; | 602 }; |
557 | 603 |
558 DECLARE_OPTIONAL_ACCESSORS(locals_names, FixedArray); | 604 DEF_SIZE(FixedArray) |
| 605 DEF_OFFSET(Instance) |
| 606 DEF_OFFSET(InterpreterHandle) |
| 607 DEF_OFFSET(InterpretedFunctions) |
| 608 DEF_OFFSET(LocalsNames) |
559 | 609 |
560 static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>); | 610 static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>); |
561 | 611 |
562 // Setup a WasmDebugInfo with an existing WasmInstance struct. | 612 // Setup a WasmDebugInfo with an existing WasmInstance struct. |
563 // Returns a pointer to the interpreter instantiated inside this | 613 // Returns a pointer to the interpreter instantiated inside this |
564 // WasmDebugInfo. | 614 // WasmDebugInfo. |
565 // Use for testing only. | 615 // Use for testing only. |
566 V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting( | 616 V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting( |
567 Handle<WasmInstanceObject>, wasm::WasmInstance*); | 617 Handle<WasmInstanceObject>, wasm::WasmInstance*); |
568 | 618 |
569 static bool IsDebugInfo(Object*); | |
570 static WasmDebugInfo* cast(Object*); | |
571 | |
572 // Set a breakpoint in the given function at the given byte offset within that | 619 // Set a breakpoint in the given function at the given byte offset within that |
573 // function. This will redirect all future calls to this function to the | 620 // function. This will redirect all future calls to this function to the |
574 // interpreter and will always pause at the given offset. | 621 // interpreter and will always pause at the given offset. |
575 static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset); | 622 static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset); |
576 | 623 |
577 // Make a set of functions always execute in the interpreter without setting | 624 // Make a set of functions always execute in the interpreter without setting |
578 // breakpoints. | 625 // breakpoints. |
579 static void RedirectToInterpreter(Handle<WasmDebugInfo>, | 626 static void RedirectToInterpreter(Handle<WasmDebugInfo>, |
580 Vector<int> func_indexes); | 627 Vector<int> func_indexes); |
581 | 628 |
(...skipping 16 matching lines...) Expand all Loading... |
598 std::unique_ptr<wasm::InterpretedFrame> GetInterpretedFrame( | 645 std::unique_ptr<wasm::InterpretedFrame> GetInterpretedFrame( |
599 Address frame_pointer, int frame_index); | 646 Address frame_pointer, int frame_index); |
600 | 647 |
601 // Unwind the interpreted stack belonging to the passed interpreter entry | 648 // Unwind the interpreted stack belonging to the passed interpreter entry |
602 // frame. | 649 // frame. |
603 void Unwind(Address frame_pointer); | 650 void Unwind(Address frame_pointer); |
604 | 651 |
605 // Returns the number of calls / function frames executed in the interpreter. | 652 // Returns the number of calls / function frames executed in the interpreter. |
606 uint64_t NumInterpretedCalls(); | 653 uint64_t NumInterpretedCalls(); |
607 | 654 |
608 DECLARE_GETTER(wasm_instance, WasmInstanceObject); | |
609 | |
610 // Update the memory view of the interpreter after executing GrowMemory in | 655 // Update the memory view of the interpreter after executing GrowMemory in |
611 // compiled code. | 656 // compiled code. |
612 void UpdateMemory(JSArrayBuffer* new_memory); | 657 void UpdateMemory(JSArrayBuffer* new_memory); |
613 | 658 |
614 // Get scope details for a specific interpreted frame. | 659 // Get scope details for a specific interpreted frame. |
615 // This returns a JSArray of length two: One entry for the global scope, one | 660 // This returns a JSArray of length two: One entry for the global scope, one |
616 // for the local scope. Both elements are JSArrays of size | 661 // for the local scope. Both elements are JSArrays of size |
617 // ScopeIterator::kScopeDetailsSize and layout as described in debug-scopes.h. | 662 // ScopeIterator::kScopeDetailsSize and layout as described in debug-scopes.h. |
618 // The global scope contains information about globals and the memory. | 663 // The global scope contains information about globals and the memory. |
619 // The local scope contains information about parameters, locals, and stack | 664 // The local scope contains information about parameters, locals, and stack |
620 // values. | 665 // values. |
621 static Handle<JSArray> GetScopeDetails(Handle<WasmDebugInfo>, | 666 static Handle<JSArray> GetScopeDetails(Handle<WasmDebugInfo>, |
622 Address frame_pointer, | 667 Address frame_pointer, |
623 int frame_index); | 668 int frame_index); |
624 }; | 669 }; |
625 | 670 |
626 class WasmInstanceWrapper : public FixedArray { | 671 class WasmInstanceWrapper : public FixedArray { |
627 public: | 672 public: |
628 static Handle<WasmInstanceWrapper> New(Isolate* isolate, | 673 enum { // -- |
629 Handle<WasmInstanceObject> instance); | 674 kWrapperInstanceObjectIndex, |
| 675 kNextInstanceWrapperIndex, |
| 676 kPreviousInstanceWrapperIndex, |
| 677 kFieldCount |
| 678 }; |
| 679 |
630 static WasmInstanceWrapper* cast(Object* fixed_array) { | 680 static WasmInstanceWrapper* cast(Object* fixed_array) { |
631 SLOW_DCHECK(IsWasmInstanceWrapper(fixed_array)); | 681 SLOW_DCHECK(IsWasmInstanceWrapper(fixed_array)); |
632 return reinterpret_cast<WasmInstanceWrapper*>(fixed_array); | 682 return reinterpret_cast<WasmInstanceWrapper*>(fixed_array); |
633 } | 683 } |
634 static bool IsWasmInstanceWrapper(Object* obj); | 684 static bool IsWasmInstanceWrapper(Object* obj); |
635 bool has_instance() { return get(kWrapperInstanceObject)->IsWeakCell(); } | 685 bool has_instance() { return get(kWrapperInstanceObjectIndex)->IsWeakCell(); } |
636 Handle<WasmInstanceObject> instance_object() { | 686 Handle<WasmInstanceObject> instance_object() { |
637 Object* obj = get(kWrapperInstanceObject); | 687 Object* obj = get(kWrapperInstanceObjectIndex); |
638 DCHECK(obj->IsWeakCell()); | 688 DCHECK(obj->IsWeakCell()); |
639 WeakCell* cell = WeakCell::cast(obj); | 689 WeakCell* cell = WeakCell::cast(obj); |
640 DCHECK(cell->value()->IsJSObject()); | 690 DCHECK(cell->value()->IsJSObject()); |
641 return handle(WasmInstanceObject::cast(cell->value())); | 691 return handle(WasmInstanceObject::cast(cell->value())); |
642 } | 692 } |
643 bool has_next() { return IsWasmInstanceWrapper(get(kNextInstanceWrapper)); } | 693 bool has_next() { |
| 694 return IsWasmInstanceWrapper(get(kNextInstanceWrapperIndex)); |
| 695 } |
644 bool has_previous() { | 696 bool has_previous() { |
645 return IsWasmInstanceWrapper(get(kPreviousInstanceWrapper)); | 697 return IsWasmInstanceWrapper(get(kPreviousInstanceWrapperIndex)); |
646 } | 698 } |
647 void set_next_wrapper(Object* obj) { | 699 void set_next_wrapper(Object* obj) { |
648 DCHECK(IsWasmInstanceWrapper(obj)); | 700 DCHECK(IsWasmInstanceWrapper(obj)); |
649 set(kNextInstanceWrapper, obj); | 701 set(kNextInstanceWrapperIndex, obj); |
650 } | 702 } |
651 void set_previous_wrapper(Object* obj) { | 703 void set_previous_wrapper(Object* obj) { |
652 DCHECK(IsWasmInstanceWrapper(obj)); | 704 DCHECK(IsWasmInstanceWrapper(obj)); |
653 set(kPreviousInstanceWrapper, obj); | 705 set(kPreviousInstanceWrapperIndex, obj); |
654 } | 706 } |
655 Handle<WasmInstanceWrapper> next_wrapper() { | 707 Handle<WasmInstanceWrapper> next_wrapper() { |
656 Object* obj = get(kNextInstanceWrapper); | 708 Object* obj = get(kNextInstanceWrapperIndex); |
657 DCHECK(IsWasmInstanceWrapper(obj)); | 709 DCHECK(IsWasmInstanceWrapper(obj)); |
658 return handle(WasmInstanceWrapper::cast(obj)); | 710 return handle(WasmInstanceWrapper::cast(obj)); |
659 } | 711 } |
660 Handle<WasmInstanceWrapper> previous_wrapper() { | 712 Handle<WasmInstanceWrapper> previous_wrapper() { |
661 Object* obj = get(kPreviousInstanceWrapper); | 713 Object* obj = get(kPreviousInstanceWrapperIndex); |
662 DCHECK(IsWasmInstanceWrapper(obj)); | 714 DCHECK(IsWasmInstanceWrapper(obj)); |
663 return handle(WasmInstanceWrapper::cast(obj)); | 715 return handle(WasmInstanceWrapper::cast(obj)); |
664 } | 716 } |
665 void reset_next_wrapper() { set_undefined(kNextInstanceWrapper); } | 717 void reset_next_wrapper() { set_undefined(kNextInstanceWrapperIndex); } |
666 void reset_previous_wrapper() { set_undefined(kPreviousInstanceWrapper); } | 718 void reset_previous_wrapper() { |
| 719 set_undefined(kPreviousInstanceWrapperIndex); |
| 720 } |
667 void reset() { | 721 void reset() { |
668 for (int kID = 0; kID < kWrapperPropertyCount; kID++) set_undefined(kID); | 722 for (int kID = 0; kID < kFieldCount; kID++) set_undefined(kID); |
669 } | 723 } |
670 | 724 |
671 private: | 725 static Handle<WasmInstanceWrapper> New(Isolate* isolate, |
672 enum { | 726 Handle<WasmInstanceObject> instance); |
673 kWrapperInstanceObject, | |
674 kNextInstanceWrapper, | |
675 kPreviousInstanceWrapper, | |
676 kWrapperPropertyCount | |
677 }; | |
678 }; | 727 }; |
679 | 728 |
680 #undef DECLARE_CASTS | 729 // TODO(titzer): these should be moved to wasm-objects-inl.h |
681 #undef DECLARE_GETTER | 730 CAST_ACCESSOR(WasmInstanceObject) |
682 #undef DECLARE_ACCESSORS | 731 CAST_ACCESSOR(WasmMemoryObject) |
683 #undef DECLARE_OPTIONAL_ACCESSORS | 732 CAST_ACCESSOR(WasmModuleObject) |
684 #undef DECLARE_OPTIONAL_GETTER | 733 CAST_ACCESSOR(WasmTableObject) |
| 734 |
| 735 // WasmModuleObject |
| 736 ACCESSORS(WasmModuleObject, compiled_module, WasmCompiledModule, |
| 737 kCompiledModuleOffset) |
| 738 |
| 739 // WasmTableObject |
| 740 ACCESSORS(WasmTableObject, functions, FixedArray, kFunctionsOffset) |
| 741 SMI_ACCESSORS(WasmTableObject, maximum_length, kMaximumLengthOffset) |
| 742 ACCESSORS(WasmTableObject, dispatch_tables, FixedArray, kDispatchTablesOffset) |
| 743 |
| 744 // WasmMemoryObject |
| 745 ACCESSORS(WasmMemoryObject, array_buffer, JSArrayBuffer, kArrayBufferOffset) |
| 746 SMI_ACCESSORS(WasmMemoryObject, maximum_pages, kMaximumPagesOffset) |
| 747 ACCESSORS(WasmMemoryObject, instances_link, WasmInstanceWrapper, |
| 748 kInstancesLinkOffset) |
| 749 |
| 750 // WasmInstanceObject |
| 751 ACCESSORS(WasmInstanceObject, compiled_module, WasmCompiledModule, |
| 752 kCompiledModuleOffset) |
| 753 ACCESSORS(WasmInstanceObject, memory_object, WasmMemoryObject, |
| 754 kMemoryObjectOffset) |
| 755 ACCESSORS(WasmInstanceObject, memory_buffer, JSArrayBuffer, kMemoryBufferOffset) |
| 756 ACCESSORS(WasmInstanceObject, globals_buffer, JSArrayBuffer, |
| 757 kGlobalsBufferOffset) |
| 758 ACCESSORS(WasmInstanceObject, debug_info, WasmDebugInfo, kDebugInfoOffset) |
| 759 ACCESSORS(WasmInstanceObject, instance_wrapper, WasmInstanceWrapper, |
| 760 kInstanceWrapperOffset) |
| 761 ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray, |
| 762 kDirectlyCalledInstancesOffset) |
| 763 |
| 764 // WasmExportedFunction |
| 765 ACCESSORS(WasmExportedFunction, instance, WasmInstanceObject, kInstanceOffset) |
| 766 SMI_ACCESSORS(WasmExportedFunction, function_index, kFunctionIndexOffset) |
| 767 |
| 768 // WasmSharedModuleData |
| 769 ACCESSORS(WasmSharedModuleData, module_bytes, SeqOneByteString, |
| 770 kModuleBytesOffset) |
| 771 ACCESSORS(WasmSharedModuleData, script, Script, kScriptOffset) |
| 772 ACCESSORS(WasmSharedModuleData, asm_js_offset_table, ByteArray, |
| 773 kAsmJsOffsetTableOffset) |
| 774 ACCESSORS(WasmSharedModuleData, breakpoint_infos, FixedArray, |
| 775 kBreakPointInfosOffset) |
| 776 |
| 777 #define OPTIONAL_ACCESSOR(holder, name, offset) \ |
| 778 bool holder::has_##name() { \ |
| 779 return !READ_FIELD(this, offset)->IsUndefined(GetIsolate()); \ |
| 780 } |
| 781 |
| 782 OPTIONAL_ACCESSOR(WasmInstanceObject, debug_info, kDebugInfoOffset) |
| 783 OPTIONAL_ACCESSOR(WasmInstanceObject, memory_buffer, kMemoryBufferOffset) |
| 784 OPTIONAL_ACCESSOR(WasmInstanceObject, memory_object, kMemoryObjectOffset) |
| 785 OPTIONAL_ACCESSOR(WasmInstanceObject, instance_wrapper, kInstanceWrapperOffset) |
| 786 |
| 787 OPTIONAL_ACCESSOR(WasmMemoryObject, instances_link, kInstancesLinkOffset) |
| 788 |
| 789 OPTIONAL_ACCESSOR(WasmSharedModuleData, breakpoint_infos, |
| 790 kBreakPointInfosOffset) |
| 791 OPTIONAL_ACCESSOR(WasmSharedModuleData, asm_js_offset_table, |
| 792 kAsmJsOffsetTableOffset) |
| 793 OPTIONAL_ACCESSOR(WasmSharedModuleData, lazy_compilation_orchestrator, |
| 794 kLazyCompilationOrchestratorOffset) |
| 795 |
| 796 ACCESSORS(WasmDebugInfo, locals_names, FixedArray, kLocalsNamesOffset) |
| 797 |
| 798 OPTIONAL_ACCESSOR(WasmDebugInfo, locals_names, kLocalsNamesOffset) |
| 799 |
| 800 inline void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) { |
| 801 // This has to be a raw access to bypass typechecking. |
| 802 WRITE_FIELD(this, kInstancesLinkOffset, isolate->heap()->undefined_value()); |
| 803 } |
| 804 |
| 805 #undef DECL_OOL_QUERY |
| 806 #undef DECL_OOL_CAST |
| 807 #undef DECL_GETTER |
| 808 #undef DECL_OPTIONAL_ACCESSORS |
| 809 #undef DECL_OPTIONAL_GETTER |
| 810 |
| 811 #include "src/objects/object-macros-undef.h" |
685 | 812 |
686 } // namespace internal | 813 } // namespace internal |
687 } // namespace v8 | 814 } // namespace v8 |
688 | 815 |
689 #endif // V8_WASM_OBJECTS_H_ | 816 #endif // V8_WASM_OBJECTS_H_ |
OLD | NEW |