History

Initial public commit for Dis VM

arr committed 10 years ago

Commit f95902eNo parent (first commit)40 files · +9358 −0Browse files

Showing the changes to src/include/runtime.h (1 of 40 files). Show all

Unified · Split

src/include/runtime.h+846−0
@@ -0,0 +1,846 @@
1//
2// Dis VM
3// File: runtime.h
4// Author: arr
5//
6
7#ifndef _DISVM_SRC_INCLUDE_RUNTIME_H_
8#define _DISVM_SRC_INCLUDE_RUNTIME_H_
9
10#include <cstdint>
11#include <cassert>
12#include <atomic>
13#include <vector>
14#include <string>
15#include <memory>
16#include <deque>
17#include <unordered_map>
18#include <mutex>
19#include <functional>
20#include "opcodes.h"
21
22namespace disvm
23{
24 // VM forward declation
25 class vm_t;
26
27 namespace runtime
28 {
29 //
30 // VM primitive data type definitions
31 //
32
33 using byte_t = uint8_t;
34 using short_word_t = int16_t;
35 using word_t = int32_t;
36 using short_real_t = float;
37 using real_t = double;
38 using big_t = int64_t;
39 using pointer_t = std::size_t *;
40 using vm_pc_t = word_t;
41
42 //
43 // VM memory management
44 //
45
46 // VM forward declation
47 class vm_alloc_t;
48
49 // Finalizer callback for allocations.
50 using vm_alloc_instance_finalizer_t = void(*)(vm_alloc_t *);
51
52 // VM type description
53 class type_descriptor_t final
54 {
55 public: // static
56 static vm_alloc_instance_finalizer_t no_finalizer;
57
58 // Create a type descriptor for type of the supplied size and pointers based on the supplied map.
59 static std::shared_ptr<const type_descriptor_t> create(const word_t size);
60 static std::shared_ptr<const type_descriptor_t> create(const word_t size, const std::vector<byte_t> &pointer_map);
61 static std::shared_ptr<const type_descriptor_t> create(
62 const word_t size,
63 const word_t pointer_map_length,
64 const byte_t *pointer_map,
65 vm_alloc_instance_finalizer_t finalizer = type_descriptor_t::no_finalizer);
66
67 private:
68 type_descriptor_t(word_t size_in_bytes, word_t map_in_bytes, const byte_t * pointer_map, vm_alloc_instance_finalizer_t finalizer);
69
70 public:
71 type_descriptor_t(const type_descriptor_t&) = delete;
72 type_descriptor_t& operator=(const type_descriptor_t&) = delete;
73
74 const word_t size_in_bytes;
75 const word_t map_in_bytes;
76 const byte_t * const pointer_map;
77 const vm_alloc_instance_finalizer_t finalizer;
78 };
79
80 // Access to type descriptors for VM intrinsic types.
81 class intrinsic_type_desc final
82 {
83 private:
84 friend vm_t;
85 static std::atomic_bool is_initialized;
86 static void initialize();
87
88 public:
89 // Templated type descriptor getter
90 template<typename IntrinsicType>
91 static std::shared_ptr<const type_descriptor_t> type();
92 };
93
94 // Type used to indicate allocated memory should be zeroed out.
95 struct zero_memory_t
96 { };
97
98 // VM memory allocation
99 class vm_alloc_t
100 {
101 public: // static
102 static const zero_memory_t zero_memory;
103
104 static void *operator new(std::size_t sz);
105 static void operator delete(void *ptr);
106
107 static vm_alloc_t *allocate(std::shared_ptr<const type_descriptor_t> td);
108 static vm_alloc_t *allocate(std::shared_ptr<const type_descriptor_t> td, const zero_memory_t &);
109 static vm_alloc_t *copy(const vm_alloc_t &other);
110 static vm_alloc_t *from_allocation(pointer_t allocation);
111
112 template <typename T>
113 static T *from_allocation(pointer_t allocation)
114 {
115 auto alloc_inst = vm_alloc_t::from_allocation(allocation);
116 assert(alloc_inst == nullptr || alloc_inst->alloc_type == intrinsic_type_desc::type<T>());
117 return dynamic_cast<T *>(alloc_inst);
118 }
119
120 protected:
121 vm_alloc_t(std::shared_ptr<const type_descriptor_t> td);
122
123 public:
124 virtual ~vm_alloc_t();
125
126 std::size_t add_ref();
127 std::size_t release();
128 std::size_t get_ref_count() const;
129
130 std::shared_ptr<const type_descriptor_t> alloc_type;
131
132 // Reserved for use by the garbage collector.
133 // This should not be accessed by any other component.
134 pointer_t gc_reserved;
135
136 public:
137 pointer_t allocation() const;
138
139 private:
140 std::atomic<std::size_t> _ref_count;
141 };
142
143 //
144 // VM intrinsic type definitions
145 //
146
147 // Type to contain the maximum UTF-8 character value
148 using rune_t = uint32_t;
149
150 // VM string type
151 class vm_string_t final : public vm_alloc_t
152 {
153 public: //static
154 static std::shared_ptr<const type_descriptor_t> type_desc();
155
156 // Compare two string objects
157 static int compare(const vm_string_t *s1, const vm_string_t *s2);
158
159 public:
160 vm_string_t();
161 vm_string_t(std::size_t encoded_str_len, const uint8_t *encoded_str);
162 vm_string_t(const vm_string_t &s1, const vm_string_t &s2);
163 vm_string_t(const vm_string_t &other, word_t begin_index, word_t end_index);
164 vm_string_t(const vm_string_t &) = delete;
165 ~vm_string_t();
166
167 // Returns this string.
168 vm_string_t &append(const vm_string_t &other);
169
170 word_t get_length() const;
171
172 rune_t get_rune(word_t index) const;
173
174 void set_rune(word_t index, rune_t value);
175
176 int compare_to(const vm_string_t *s) const;
177
178 const char *str() const;
179
180 private:
181 word_t _length;
182 word_t _length_max;
183 mutable std::mutex _encoded_str_lock;
184 mutable char *_encoded_str;
185 mutable union string_memory_t
186 {
187 uint8_t local[16]; // Optimization for short strings
188 uint8_t *alloc;
189 } _mem;
190
191 uint8_t _character_size; // 1 byte (ASCII) or 4 bytes (multi-byte)
192 bool _is_alloc;
193 };
194
195 // VM array type
196 class vm_array_t final : public vm_alloc_t
197 {
198 public: //static
199 static std::shared_ptr<const type_descriptor_t> type_desc();
200
201 public:
202 vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count);
203 vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count, const zero_memory_t&);
204 vm_array_t(vm_array_t *original, word_t begin_index, word_t count);
205 vm_array_t(const vm_string_t *s);
206 ~vm_array_t();
207
208 std::shared_ptr<const type_descriptor_t> get_element_type() const;
209
210 word_t get_length() const;
211
212 pointer_t at(word_t index) const;
213
214 template<typename T>
215 T& at(word_t index) const
216 {
217 return *reinterpret_cast<T *>(at(index));
218 }
219
220 // Copy the contents of the source array into this array starting at index
221 void copy_from(const vm_array_t &source, word_t this_begin_index);
222
223 private:
224 std::shared_ptr<const type_descriptor_t> _element_type;
225 vm_array_t *_original;
226 word_t _length;
227 byte_t *_arr;
228 };
229
230 // VM list type
231 class vm_list_t final : public vm_alloc_t
232 {
233 public: //static
234 static std::shared_ptr<const type_descriptor_t> type_desc();
235
236 public:
237 vm_list_t(std::shared_ptr<const type_descriptor_t> td, vm_list_t *tail = nullptr);
238 ~vm_list_t();
239
240 std::shared_ptr<const type_descriptor_t> get_element_type() const;
241
242 word_t get_length() const;
243
244 vm_list_t* get_tail() const;
245
246 vm_list_t* drop_tail();
247
248 // Returns a pointer to the value
249 pointer_t value() const;
250
251 private:
252 std::shared_ptr<const type_descriptor_t> _element_type;
253 vm_list_t *_tail;
254
255 // Utilizing a union so that all value types can
256 // be stored without allocating any extra memory.
257 mutable union element_memory_t
258 {
259 pointer_t alloc;
260 uint64_t local;
261 } _mem;
262
263 const bool _is_alloc;
264 };
265
266 // VM forward declation
267 class vm_channel_t;
268
269 // VM request mutex
270 struct vm_request_mutex_t
271 {
272 vm_request_mutex_t();
273
274 std::mutex pending_request_lock;
275 bool pending_request;
276 };
277
278 // VM channel request
279 class vm_channel_request_t final
280 {
281 public:
282 // Create a request using the ID of the requesting thread and an associated request mutex.
283 vm_channel_request_t(uint32_t thread_id, vm_request_mutex_t &request_mutex);
284
285 uint32_t thread_id;
286
287 // Callback used to indicate the request was handled in the supplied channel.
288 // This is only called in the event the request was not immediately serviced.
289 std::function<void(const vm_channel_t &)> request_handled_callback;
290
291 // Data of the request
292 pointer_t data;
293
294 std::reference_wrapper<vm_request_mutex_t> request_mutex;
295 };
296
297 // VM channel type
298 class vm_channel_t final : public vm_alloc_t
299 {
300 public: //static
301 static std::shared_ptr<const type_descriptor_t> type_desc();
302
303 public:
304 vm_channel_t(
305 std::shared_ptr<const type_descriptor_t> td,
306 std::function<void(pointer_t, pointer_t, const type_descriptor_t *)> transfer,
307 word_t buffer_len);
308 ~vm_channel_t();
309
310 std::shared_ptr<const type_descriptor_t> get_data_type() const;
311
312 // Send data into the channel.
313 // Returns true if the data was sent, otherwise request is queued and false returned.
314 bool send_data(vm_channel_request_t &send_request);
315
316 // Receive data from the channel.
317 // Returns true if data was received, otherwise request is queued and false returned.
318 bool receive_data(vm_channel_request_t &receive_request);
319
320 // Cancel an outstanding request from a thread.
321 void cancel_request(uint32_t thread_id);
322
323 private:
324 // Try to send data into the channel buffer.
325 // Returns true if data was sent to buffer, otherwise false.
326 bool try_send_to_buffer(vm_channel_request_t &send_request);
327
328 // Try to receive data from the channel buffer.
329 // Returns true if data was received from buffer, otherwise false.
330 bool try_receive_from_buffer(vm_channel_request_t &receive_request);
331
332 private:
333 std::mutex _data_lock;
334 std::shared_ptr<const type_descriptor_t> _data_type;
335 std::function<void(pointer_t, pointer_t, const type_descriptor_t *)> _data_transfer;
336
337 vm_array_t *_data_buffer;
338 uint32_t _data_buffer_head; // Next element to remove from buffer
339 uint32_t _data_buffer_count; // Count of elements in buffer
340
341 using request_queue_t = std::deque<vm_channel_request_t>;
342 request_queue_t _data_senders;
343 request_queue_t _data_receivers;
344 };
345
346 // Alt channel entry.
347 static_assert(sizeof(word_t) == sizeof(pointer_t), "Alt channel stack layout will be invalid.");
348 struct vm_alt_channel_stack_layout_t
349 {
350 word_t alloc;
351 word_t data;
352 };
353
354 // Alt channel layout as defined by the specification for the 'alt' instruction.
355 struct vm_alt_stack_layout_t
356 {
357 word_t send_count;
358 word_t receive_count;
359 vm_alt_channel_stack_layout_t channels[1];
360 };
361
362 // Runtime constants
363 struct runtime_constants
364 {
365 static const auto nil = std::size_t{ 0 };
366
367 static const auto invalid_program_counter = vm_pc_t{ ~0 };
368
369 static const auto default_register_count = std::size_t{ 4 };
370 static const auto default_register_size_bytes = sizeof(word_t);
371
372 // See VM frame definition
373 static const auto fixed_point_register_1_frame_offset = std::size_t{ default_register_count * default_register_size_bytes };
374 static const auto fixed_point_register_2_frame_offset = fixed_point_register_1_frame_offset + (2 * default_register_size_bytes);
375 };
376
377 // Addressing mode for middle instruction data
378 enum class address_mode_middle_t
379 {
380 none = 0,
381 small_immediate = 1,
382 small_offset_indirect_fp = 2,
383 small_offset_indirect_mp = 3,
384 };
385
386 // Middle instruction data
387 struct middle_data_t
388 {
389 address_mode_middle_t mode;
390 word_t register1;
391 };
392
393 // Addressing mode for source and destination instruction data
394 enum class address_mode_t
395 {
396 offset_indirect_mp = 0,
397 offset_indirect_fp = 1,
398 immediate = 2,
399 none = 3,
400 offset_double_indirect_mp = 4,
401 offset_double_indirect_fp = 5,
402 reserved_1 = 6,
403 reserved_2 = 7,
404 };
405
406 // Source and destination instruction data
407 struct inst_data_generic_t
408 {
409 address_mode_t mode;
410 word_t register1;
411 word_t register2;
412 };
413
414 using src_data_t = inst_data_generic_t;
415 using dest_data_t = inst_data_generic_t;
416
417 // VM forward declation
418 class vm_registers_t;
419
420 // Instruction execution operation
421 using vm_exec_t = void(*)(vm_registers_t &, vm_t &);
422
423 // Opcode execution operation
424 struct vm_exec_op_t
425 {
426 opcode_t opcode;
427 src_data_t source;
428 middle_data_t middle;
429 dest_data_t destination;
430 };
431
432 // VM Instruction (code section of module)
433 union vm_instruction_t
434 {
435 vm_exec_op_t op;
436 vm_exec_t native;
437 };
438
439 // Flags that dictate the runtime operations of the module
440 // [SPEC] Values past 'shared_module' are not fully documented.
441 enum class runtime_flags_t
442 {
443 must_compile = 1 << 0,
444 dont_compile = 1 << 1,
445 share_module = 1 << 2, // [TODO] Respect this setting
446 reserved_1 = 1 << 3, // DYNMOD
447 has_import_deprecated = 1 << 4,
448 has_handler = 1 << 5,
449 has_import = 1 << 6,
450
451 builtin = 1 << 7,
452 };
453
454 // Module header
455 struct header_t
456 {
457 word_t magic_number;
458 struct
459 {
460 word_t length;
461 std::unique_ptr<byte_t[]> signature;
462 } Signature;
463
464 runtime_flags_t runtime_flag;
465 word_t stack_extent;
466 word_t code_size;
467 word_t data_size;
468 word_t type_size;
469 word_t export_size;
470 vm_pc_t entry_pc;
471 word_t entry_type; // Stack frame type
472 };
473
474 // Export function entry
475 struct export_function_t
476 {
477 export_function_t() = default;
478 export_function_t(export_function_t &&);
479
480 export_function_t(const export_function_t &) = delete;
481 export_function_t &operator=(const export_function_t &) = delete;
482
483 ~export_function_t();
484
485 vm_pc_t pc;
486 word_t frame_type;
487 word_t sig;
488 std::unique_ptr<vm_string_t> name;
489 };
490
491 // Import function entry
492 struct import_function_t
493 {
494 import_function_t() = default;
495 import_function_t(import_function_t &&);
496
497 import_function_t(const import_function_t &) = delete;
498 import_function_t &operator=(const import_function_t &) = delete;
499
500 ~import_function_t();
501
502 word_t sig;
503 std::unique_ptr<vm_string_t> name;
504 };
505
506 // Import table for module
507 struct import_vm_module_t
508 {
509 import_vm_module_t() = default;
510 import_vm_module_t(import_vm_module_t &&);
511
512 import_vm_module_t(const import_vm_module_t &) = delete;
513 import_vm_module_t &operator=(const import_vm_module_t &) = delete;
514
515 ~import_vm_module_t() = default;
516
517 std::vector<import_function_t> functions;
518 };
519
520 // Exception entry for handler
521 struct exception_t
522 {
523 exception_t() = default;
524 exception_t(exception_t &&);
525
526 exception_t(const exception_t &) = delete;
527 exception_t &operator=(const exception_t &) = delete;
528
529 ~exception_t();
530
531 vm_pc_t pc;
532 std::unique_ptr<vm_string_t> name;
533 };
534
535 // Exception handler
536 struct handler_t
537 {
538 handler_t() = default;
539 handler_t(handler_t &&);
540
541 handler_t(const handler_t &) = delete;
542 handler_t &operator=(const handler_t &) = delete;
543
544 ~handler_t() = default;
545
546 // Byte offset in the handling frame the exception should be placed.
547 word_t exception_offset;
548 vm_pc_t begin_pc;
549 vm_pc_t end_pc;
550
551 // Number of cases in exception table where the caught exception is of exception type.
552 // See exceptions in Limbo language for details.
553 word_t exception_type_count;
554
555 std::shared_ptr<const type_descriptor_t> type_desc;
556 std::vector<exception_t> exception_table;
557 };
558
559 using code_section_t = std::vector<vm_instruction_t>;
560 using type_section_map_t = std::vector<std::shared_ptr<const type_descriptor_t>>;
561 using export_section_t = std::unordered_multimap<word_t, const export_function_t>;
562 using import_section_t = std::vector<import_vm_module_t>;
563 using handler_section_t = std::vector<handler_t>;
564
565 // VM module
566 struct vm_module_t
567 {
568 vm_module_t() = default;
569 vm_module_t(const vm_module_t &) = delete;
570 vm_module_t &operator=(const vm_module_t &) = delete;
571
572 ~vm_module_t();
573
574 // Contains a magic number, digital signature, runtime flags, sizes of the other sections, and a description of the entry point
575 header_t header;
576
577 // Describes a sequence of instructions for the virtual machine
578 code_section_t code_section;
579
580 // template module pointer
581 std::unique_ptr<vm_alloc_t> original_mp;
582
583 // Type descriptors describing the layout of pointers within data types
584 type_section_map_t type_section;
585
586 // Module name
587 std::unique_ptr<vm_string_t> module_name;
588
589 // List of functions exported by this module
590 export_section_t export_section;
591
592 // List of all functions imported from other modules
593 import_section_t import_section;
594
595 // Lists all exception handlers declared in the module
596 handler_section_t handler_section;
597 };
598
599 // Reference to a function in an imported module.
600 struct vm_module_function_ref_t
601 {
602 vm_pc_t entry_pc;
603 word_t frame_type;
604 };
605
606 // Reference to a module
607 class vm_module_ref_t final : public vm_alloc_t
608 {
609 public: //static
610 static std::shared_ptr<const type_descriptor_t> type_desc();
611
612 public:
613 vm_module_ref_t(std::shared_ptr<const vm_module_t> module);
614 vm_module_ref_t(std::shared_ptr<const vm_module_t> module, const import_vm_module_t &imports);
615 ~vm_module_ref_t();
616
617 std::shared_ptr<const vm_module_t> module;
618 vm_alloc_t *mp_base;
619 const code_section_t &code_section;
620 const type_section_map_t &type_section;
621
622 bool is_builtin_module() const;
623 const vm_module_function_ref_t& get_function_ref(word_t index) const;
624
625 private:
626 const bool _builtin_module;
627 std::unique_ptr<vm_array_t> _function_refs;
628 };
629
630 // VM stack frame
631 class vm_frame_t final
632 {
633 public:
634 vm_frame_t(std::shared_ptr<const type_descriptor_t> &frame_type);
635 ~vm_frame_t();
636
637 std::shared_ptr<const type_descriptor_t> frame_type;
638
639 // Copy the frame contents
640 void copy_frame_contents(const vm_frame_t &other);
641
642 // Pointer to the base of the frame.
643 pointer_t base() const;
644
645 template<typename T>
646 T& base() const
647 {
648 return *reinterpret_cast<T *>(base());
649 }
650
651 vm_pc_t &prev_pc() const;
652 vm_frame_t *&prev_frame() const;
653
654 // This is only set if this frame represents a module transition.
655 vm_module_ref_t *&prev_module_ref() const;
656
657 // Fixed point register positions in frame
658 // [SPEC] These are not defined in the vm spec.
659
660 // 'Stmp' in libinterp/xec.c
661 pointer_t fixed_point_register_1() const;
662
663 // 'Dtmp' in libinterp/xec.c
664 pointer_t fixed_point_register_2() const;
665 };
666
667 // Callback for stack walk.
668 // Returning 'false' during the stack walk will terminate the walk.
669 // The second parameter is reserved for internal use by the VM and should not be manipulated.
670 using vm_stack_walk_callback_t = std::function<bool(const vm_frame_t *f, const void *reserved)>;
671
672 // VM stack
673 class vm_stack_t final
674 {
675 public:
676 vm_stack_t(std::size_t stack_extent);
677 ~vm_stack_t();
678
679 // Allocate a new frame instance.
680 vm_frame_t *alloc_frame(std::shared_ptr<const type_descriptor_t> frame_type);
681
682 // Push the latest allocated frame as the new top frame.
683 vm_frame_t *push_frame();
684
685 // Remove the top frame and return the next frame in the stack.
686 vm_frame_t *pop_frame();
687
688 // Return the current top frame.
689 vm_frame_t *peek_frame() const;
690
691 // Walk the stack getting a callback for each frame.
692 // This function is __not__ thread safe.
693 void walk_stack(vm_stack_walk_callback_t callback) const;
694
695 private:
696 std::unique_ptr<vm_alloc_t> _mem;
697 };
698
699 // Walk the supplied stack and faulting module find the handler, handling stack frame, and program counter for the supplied exception ID.
700 // If an exception handler cannot be found an 'unhandled_user_exception' exception will be thrown.
701 std::tuple<const handler_t *, vm_frame_t *, vm_pc_t> find_exception_handler(
702 const vm_stack_t &stack,
703 const vm_module_ref_t &faulting_module,
704 const vm_pc_t faulting_pc,
705 const vm_string_t &exception_id);
706
707 // VM thread states
708 enum class vm_thread_state_t
709 {
710 unknown = 0,
711
712 blocked_in_alt, // blocked in alt instruction
713 blocked_sending, // blocked waiting to send
714 blocked_receiving, // blocked waiting to receive
715
716 debug, // thread is running under a debugger
717 ready, // ready to run
718 running,
719
720 release, // interpreter released - executing non-vm instructions
721
722 exiting, // exit instruction
723 empty_stack,
724
725 broken, // thread crashed
726 };
727
728 // Forward declaration
729 class vm_thread_t;
730
731 // VM registers
732 class vm_registers_t
733 {
734 public:
735 vm_registers_t(
736 const vm_thread_t &thread,
737 vm_module_ref_t &entry);
738 ~vm_registers_t();
739
740 const vm_thread_t &thread;
741 vm_stack_t stack; // Frame pointer access (FP)
742 vm_pc_t pc; // Program counter (Index into module code section)
743 vm_alloc_t *mp_base; // Module data base pointer (MP)
744 vm_module_ref_t *module_ref; // Module reference
745 vm_request_mutex_t request_mutex;
746 vm_thread_state_t current_thread_state;
747 pointer_t src;
748 pointer_t mid;
749 pointer_t dest;
750 };
751
752 // VM thread
753 class vm_thread_t final : public vm_alloc_t
754 {
755 public: //static
756 static std::shared_ptr<const type_descriptor_t> type_desc();
757
758 public:
759 vm_thread_t(
760 vm_module_ref_t &entry,
761 uint32_t parent_thread_id);
762 vm_thread_t(
763 vm_module_ref_t &entry,
764 const vm_frame_t &initial_frame,
765 vm_pc_t start_pc,
766 uint32_t parent_thread_id);
767
768 ~vm_thread_t();
769
770 vm_thread_state_t execute(vm_t &virtual_machine, uint32_t quanta);
771
772 vm_thread_state_t get_state() const;
773
774 uint32_t get_thread_id() const;
775
776 uint32_t get_parent_thread_id() const;
777
778 const vm_registers_t& get_registers() const;
779
780 private:
781 const uint32_t _thread_id;
782 const uint32_t _parent_thread_id;
783 vm_registers_t _registers;
784 };
785
786 //
787 // VM interfaces
788 //
789
790 // VM thread scheduler control interface
791 class vm_scheduler_control_t
792 {
793 public:
794 virtual ~vm_scheduler_control_t() = 0;
795
796 // Indicates the scheduler should enqueue the blocked thread with the supplied ID.
797 // There is no indication if this function failed or succeeded.
798 virtual void enqueue_blocked_thread(uint32_t thread_id) = 0;
799
800 // Get all VM threads
801 virtual std::vector<std::shared_ptr<const vm_thread_t>> get_all_threads() const = 0;
802 };
803
804 // VM thread scheduler interface
805 class vm_scheduler_t
806 {
807 public:
808 virtual ~vm_scheduler_t() = 0;
809
810 // Returns true if there are no vm threads executing, scheduled to be executed, or blocked.
811 virtual bool is_idle() const = 0;
812
813 // Get controller
814 virtual vm_scheduler_control_t &get_controller() const = 0;
815
816 // Schedule the supplied thread for execution
817 virtual const vm_thread_t& schedule_thread(std::unique_ptr<vm_thread_t> thread) = 0;
818 };
819
820 // VM garbage collector interface
821 class vm_garbage_collector_t
822 {
823 public:
824 // The supplied allocation is guaranteed to be valid for the lifetime of the callback.
825 using vm_alloc_callback_t = std::function<void(const vm_alloc_t *)>;
826
827 public:
828 virtual ~vm_garbage_collector_t() = 0;
829
830 // Supply an allocation for the collector to track.
831 // Note that it is assumed the collector implementation will increment the reference count on the supplied alloc.
832 virtual void track_allocation(vm_alloc_t *alloc) = 0;
833
834 // Enumerate allocations that are being tracked by the collector.
835 // See callback type description.
836 virtual void enum_tracked_allocations(vm_alloc_callback_t callback) const = 0;
837
838 // Called by the scheduler to inform the collector it should attempt to free resources.
839 // All VM threads are guaranteed to be idle when called.
840 // Returns true if the collection algorithm was run, otherwise false.
841 virtual bool collect(std::vector<std::shared_ptr<const vm_thread_t>> &threads) = 0;
842 };
843 }
844}
845
846#endif // _DISVM_SRC_INCLUDE_RUNTIME_H_

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t