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" |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>, | 214 static void SetBreakpointsOnNewInstance(Handle<WasmSharedModuleData>, |
215 Handle<WasmInstanceObject>); | 215 Handle<WasmInstanceObject>); |
216 | 216 |
217 static void PrepareForLazyCompilation(Handle<WasmSharedModuleData>); | 217 static void PrepareForLazyCompilation(Handle<WasmSharedModuleData>); |
218 | 218 |
219 private: | 219 private: |
220 DECLARE_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign); | 220 DECLARE_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign); |
221 friend class WasmCompiledModule; | 221 friend class WasmCompiledModule; |
222 }; | 222 }; |
223 | 223 |
| 224 // This represents the set of wasm compiled functions, together |
| 225 // with all the information necessary for re-specializing them. |
| 226 // |
| 227 // We specialize wasm functions to their instance by embedding: |
| 228 // - raw interior pointers into the backing store of the array buffer |
| 229 // used as memory of a particular WebAssembly.Instance object. |
| 230 // - bounds check limits, computed at compile time, relative to the |
| 231 // size of the memory. |
| 232 // - the objects representing the function tables and signature tables |
| 233 // - raw pointer to the globals buffer. |
| 234 // |
| 235 // Even without instantiating, we need values for all of these parameters. |
| 236 // We need to track these values to be able to create new instances and |
| 237 // to be able to serialize/deserialize. |
| 238 // The design decisions for how we track these values is not too immediate, |
| 239 // and it deserves a summary. The "tricky" ones are: memory, globals, and |
| 240 // the tables (signature and functions). |
| 241 // The first 2 (memory & globals) are embedded as raw pointers to native |
| 242 // buffers. All we need to track them is the start addresses and, in the |
| 243 // case of memory, the size. We model all of them as HeapNumbers, because |
| 244 // we need to store size_t values (for addresses), and potentially full |
| 245 // 32 bit unsigned values for the size. Smis are 31 bits. |
| 246 // For tables, we need to hold a reference to the JS Heap object, because |
| 247 // we embed them as objects, and they may move. |
224 class WasmCompiledModule : public FixedArray { | 248 class WasmCompiledModule : public FixedArray { |
225 public: | 249 public: |
226 enum Fields { kFieldCount }; | 250 enum Fields { kFieldCount }; |
227 | 251 |
228 static WasmCompiledModule* cast(Object* fixed_array) { | 252 static WasmCompiledModule* cast(Object* fixed_array) { |
229 SLOW_DCHECK(IsWasmCompiledModule(fixed_array)); | 253 SLOW_DCHECK(IsWasmCompiledModule(fixed_array)); |
230 return reinterpret_cast<WasmCompiledModule*>(fixed_array); | 254 return reinterpret_cast<WasmCompiledModule*>(fixed_array); |
231 } | 255 } |
232 | 256 |
233 #define WCM_OBJECT_OR_WEAK(TYPE, NAME, ID, TYPE_CHECK) \ | 257 #define WCM_OBJECT_OR_WEAK(TYPE, NAME, ID, TYPE_CHECK) \ |
(...skipping 26 matching lines...) Expand all Loading... |
260 } \ | 284 } \ |
261 \ | 285 \ |
262 void reset_##NAME() { set_undefined(ID); } | 286 void reset_##NAME() { set_undefined(ID); } |
263 | 287 |
264 #define WCM_OBJECT(TYPE, NAME) \ | 288 #define WCM_OBJECT(TYPE, NAME) \ |
265 WCM_OBJECT_OR_WEAK(TYPE, NAME, kID_##NAME, obj->Is##TYPE()) | 289 WCM_OBJECT_OR_WEAK(TYPE, NAME, kID_##NAME, obj->Is##TYPE()) |
266 | 290 |
267 #define WCM_WASM_OBJECT(TYPE, NAME) \ | 291 #define WCM_WASM_OBJECT(TYPE, NAME) \ |
268 WCM_OBJECT_OR_WEAK(TYPE, NAME, kID_##NAME, TYPE::Is##TYPE(obj)) | 292 WCM_OBJECT_OR_WEAK(TYPE, NAME, kID_##NAME, TYPE::Is##TYPE(obj)) |
269 | 293 |
270 #define WCM_SMALL_NUMBER(TYPE, NAME) \ | 294 #define WCM_SMALL_FIXED_NUMBER(TYPE, NAME) \ |
271 TYPE NAME() const { \ | 295 TYPE NAME() const { \ |
272 return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \ | 296 return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \ |
273 } \ | 297 } \ |
274 void set_##NAME(TYPE value) { set(kID_##NAME, Smi::FromInt(value)); } | 298 void set_##NAME(TYPE value) { set(kID_##NAME, Smi::FromInt(value)); } |
275 | 299 |
| 300 #define WCM_SMALL_NUMBER(TYPE, NAME) \ |
| 301 TYPE NAME() const { \ |
| 302 return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \ |
| 303 } \ |
| 304 void set_##NAME(TYPE value) { set(kID_##NAME, Smi::FromInt(value)); } \ |
| 305 bool has_##NAME() const { return get(kID_##NAME)->IsSmi(); } |
| 306 |
276 #define WCM_WEAK_LINK(TYPE, NAME) \ | 307 #define WCM_WEAK_LINK(TYPE, NAME) \ |
277 WCM_OBJECT_OR_WEAK(WeakCell, weak_##NAME, kID_##NAME, obj->IsWeakCell()); \ | 308 WCM_OBJECT_OR_WEAK(WeakCell, weak_##NAME, kID_##NAME, obj->IsWeakCell()); \ |
278 \ | 309 \ |
279 Handle<TYPE> NAME() const { \ | 310 Handle<TYPE> NAME() const { \ |
280 return handle(TYPE::cast(weak_##NAME()->value())); \ | 311 return handle(TYPE::cast(weak_##NAME()->value())); \ |
281 } | 312 } |
282 | 313 |
283 #define CORE_WCM_PROPERTY_TABLE(MACRO) \ | 314 #define WCM_LARGE_NUMBER(TYPE, NAME) \ |
284 MACRO(WASM_OBJECT, WasmSharedModuleData, shared) \ | 315 TYPE NAME() const { \ |
285 MACRO(OBJECT, Context, native_context) \ | 316 Object* value = get(kID_##NAME); \ |
286 MACRO(SMALL_NUMBER, uint32_t, num_imported_functions) \ | 317 DCHECK(value->IsMutableHeapNumber()); \ |
287 MACRO(OBJECT, FixedArray, code_table) \ | 318 return static_cast<TYPE>(HeapNumber::cast(value)->value()); \ |
288 MACRO(OBJECT, FixedArray, weak_exported_functions) \ | 319 } \ |
289 MACRO(OBJECT, FixedArray, function_tables) \ | 320 \ |
290 MACRO(OBJECT, FixedArray, signature_tables) \ | 321 void set_##NAME(TYPE value) { \ |
291 MACRO(OBJECT, FixedArray, empty_function_tables) \ | 322 Object* number = get(kID_##NAME); \ |
292 MACRO(OBJECT, JSArrayBuffer, memory) \ | 323 DCHECK(number->IsMutableHeapNumber()); \ |
293 MACRO(SMALL_NUMBER, uint32_t, min_mem_pages) \ | 324 HeapNumber::cast(number)->set_value(static_cast<double>(value)); \ |
294 MACRO(SMALL_NUMBER, uint32_t, max_mem_pages) \ | 325 } \ |
295 MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \ | 326 \ |
296 MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \ | 327 static void recreate_##NAME(Handle<WasmCompiledModule> obj, \ |
297 MACRO(WEAK_LINK, JSObject, owning_instance) \ | 328 Factory* factory, TYPE init_val) { \ |
| 329 Handle<HeapNumber> number = factory->NewHeapNumber( \ |
| 330 static_cast<double>(init_val), MutableMode::MUTABLE, TENURED); \ |
| 331 obj->set(kID_##NAME, *number); \ |
| 332 } \ |
| 333 bool has_##NAME() const { return get(kID_##NAME)->IsMutableHeapNumber(); } |
| 334 |
| 335 #define CORE_WCM_PROPERTY_TABLE(MACRO) \ |
| 336 MACRO(WASM_OBJECT, WasmSharedModuleData, shared) \ |
| 337 MACRO(OBJECT, Context, native_context) \ |
| 338 MACRO(SMALL_FIXED_NUMBER, uint32_t, num_imported_functions) \ |
| 339 MACRO(OBJECT, FixedArray, code_table) \ |
| 340 MACRO(OBJECT, FixedArray, weak_exported_functions) \ |
| 341 MACRO(OBJECT, FixedArray, function_tables) \ |
| 342 MACRO(OBJECT, FixedArray, signature_tables) \ |
| 343 MACRO(OBJECT, FixedArray, empty_function_tables) \ |
| 344 MACRO(LARGE_NUMBER, size_t, embedded_mem_start) \ |
| 345 MACRO(LARGE_NUMBER, size_t, globals_start) \ |
| 346 MACRO(LARGE_NUMBER, uint32_t, embedded_mem_size) \ |
| 347 MACRO(SMALL_FIXED_NUMBER, uint32_t, min_mem_pages) \ |
| 348 MACRO(SMALL_FIXED_NUMBER, uint32_t, max_mem_pages) \ |
| 349 MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \ |
| 350 MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \ |
| 351 MACRO(WEAK_LINK, JSObject, owning_instance) \ |
298 MACRO(WEAK_LINK, WasmModuleObject, wasm_module) | 352 MACRO(WEAK_LINK, WasmModuleObject, wasm_module) |
299 | 353 |
300 #if DEBUG | 354 #if DEBUG |
301 #define DEBUG_ONLY_TABLE(MACRO) MACRO(SMALL_NUMBER, uint32_t, instance_id) | 355 #define DEBUG_ONLY_TABLE(MACRO) MACRO(SMALL_NUMBER, uint32_t, instance_id) |
302 #else | 356 #else |
303 #define DEBUG_ONLY_TABLE(IGNORE) | 357 #define DEBUG_ONLY_TABLE(IGNORE) |
304 uint32_t instance_id() const { return static_cast<uint32_t>(-1); } | 358 uint32_t instance_id() const { return static_cast<uint32_t>(-1); } |
305 #endif | 359 #endif |
306 | 360 |
307 #define WCM_PROPERTY_TABLE(MACRO) \ | 361 #define WCM_PROPERTY_TABLE(MACRO) \ |
308 CORE_WCM_PROPERTY_TABLE(MACRO) \ | 362 CORE_WCM_PROPERTY_TABLE(MACRO) \ |
309 DEBUG_ONLY_TABLE(MACRO) | 363 DEBUG_ONLY_TABLE(MACRO) |
310 | 364 |
311 private: | 365 private: |
312 enum PropertyIndices { | 366 enum PropertyIndices { |
313 #define INDICES(IGNORE1, IGNORE2, NAME) kID_##NAME, | 367 #define INDICES(IGNORE1, IGNORE2, NAME) kID_##NAME, |
314 WCM_PROPERTY_TABLE(INDICES) Count | 368 WCM_PROPERTY_TABLE(INDICES) Count |
315 #undef INDICES | 369 #undef INDICES |
316 }; | 370 }; |
317 | 371 |
318 public: | 372 public: |
319 static Handle<WasmCompiledModule> New(Isolate* isolate, | 373 static Handle<WasmCompiledModule> New(Isolate* isolate, |
320 Handle<WasmSharedModuleData> shared); | 374 Handle<WasmSharedModuleData> shared); |
321 | 375 |
322 static Handle<WasmCompiledModule> Clone(Isolate* isolate, | 376 static Handle<WasmCompiledModule> Clone(Isolate* isolate, |
323 Handle<WasmCompiledModule> module) { | 377 Handle<WasmCompiledModule> module); |
324 Handle<WasmCompiledModule> ret = Handle<WasmCompiledModule>::cast( | 378 static void Reset(Isolate* isolate, WasmCompiledModule* module); |
325 isolate->factory()->CopyFixedArray(module)); | 379 |
326 ret->InitId(); | 380 Address GetEmbeddedMemStartOrNull() const { |
327 ret->reset_weak_owning_instance(); | 381 DisallowHeapAllocation no_gc; |
328 ret->reset_weak_next_instance(); | 382 if (has_embedded_mem_start()) { |
329 ret->reset_weak_prev_instance(); | 383 return reinterpret_cast<Address>(embedded_mem_start()); |
330 ret->reset_weak_exported_functions(); | 384 } |
331 return ret; | 385 return nullptr; |
| 386 } |
| 387 |
| 388 Address GetGlobalsStartOrNull() const { |
| 389 DisallowHeapAllocation no_gc; |
| 390 if (has_globals_start()) { |
| 391 return reinterpret_cast<Address>(globals_start()); |
| 392 } |
| 393 return nullptr; |
332 } | 394 } |
333 | 395 |
334 uint32_t mem_size() const; | 396 uint32_t mem_size() const; |
335 uint32_t default_mem_size() const; | 397 uint32_t default_mem_size() const; |
336 | 398 |
| 399 void ResetSpecializationMemInfoIfNeeded(); |
| 400 static void SetSpecializationMemInfoFrom( |
| 401 Factory* factory, Handle<WasmCompiledModule> compiled_module, |
| 402 Handle<JSArrayBuffer> buffer); |
| 403 static void SetGlobalsStartAddressFrom( |
| 404 Factory* factory, Handle<WasmCompiledModule> compiled_module, |
| 405 Handle<JSArrayBuffer> buffer); |
| 406 |
337 #define DECLARATION(KIND, TYPE, NAME) WCM_##KIND(TYPE, NAME) | 407 #define DECLARATION(KIND, TYPE, NAME) WCM_##KIND(TYPE, NAME) |
338 WCM_PROPERTY_TABLE(DECLARATION) | 408 WCM_PROPERTY_TABLE(DECLARATION) |
339 #undef DECLARATION | 409 #undef DECLARATION |
340 | 410 |
341 // Allow to call method on WasmSharedModuleData also on this object. | 411 // Allow to call method on WasmSharedModuleData also on this object. |
342 #define FORWARD_SHARED(type, name) \ | 412 #define FORWARD_SHARED(type, name) \ |
343 type name() { return shared()->name(); } | 413 type name() { return shared()->name(); } |
344 FORWARD_SHARED(SeqOneByteString*, module_bytes) | 414 FORWARD_SHARED(SeqOneByteString*, module_bytes) |
345 FORWARD_SHARED(wasm::WasmModule*, module) | 415 FORWARD_SHARED(wasm::WasmModule*, module) |
346 FORWARD_SHARED(Script*, script) | 416 FORWARD_SHARED(Script*, script) |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 }; | 625 }; |
556 }; | 626 }; |
557 | 627 |
558 #undef DECLARE_ACCESSORS | 628 #undef DECLARE_ACCESSORS |
559 #undef DECLARE_OPTIONAL_ACCESSORS | 629 #undef DECLARE_OPTIONAL_ACCESSORS |
560 | 630 |
561 } // namespace internal | 631 } // namespace internal |
562 } // namespace v8 | 632 } // namespace v8 |
563 | 633 |
564 #endif // V8_WASM_OBJECTS_H_ | 634 #endif // V8_WASM_OBJECTS_H_ |
OLD | NEW |