Skip to content
This repository
Newer
Older
100644 493 lines (391 sloc) 12.644 kb
d769c944 »
2008-03-25 Initial work on new C++ VM
1 #include "vm.hpp"
2 #include "objectmemory.hpp"
9eb47483 »
2008-04-20 Flesh out Task considerable more
3 #include "event.hpp"
4 #include "global_cache.hpp"
152cc4c4 »
2008-07-05 Initial LLVM integration work.
5 #include "llvm.hpp"
3a0e9a46 »
2008-10-19 Renamed vm/object.hpp to vm/object_utils.hpp. File/#include shuffling.
6
7 #include "vm/object_utils.hpp"
8
6ac48bd3 »
2008-08-01 Fixed a LOT of dependencies by stripping objects.hpp and prelude.hpp …
9 #include "builtin/class.hpp"
10 #include "builtin/contexts.hpp"
11 #include "builtin/fixnum.hpp"
12 #include "builtin/list.hpp"
13 #include "builtin/symbol.hpp"
14 #include "builtin/thread.hpp"
15 #include "builtin/tuple.hpp"
16 #include "builtin/string.hpp"
58f050c5 »
2008-09-09 Ensure probe variables are initialized.
17 #include "builtin/taskprobe.hpp"
d769c944 »
2008-03-25 Initial work on new C++ VM
18
b09a24c4 »
2008-12-12 Wire the JIT in via MachineMethod
19 #include "config_parser.hpp"
6c31ab68 »
2009-01-05 Add cli switch to enable jit
20 #include "config.h"
8dc150ee »
2008-08-14 Implement ConfigParser, wire in into RUBY_CONFIG.
21
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
22 #include <iostream>
f9ec582b »
2008-10-10 Add preemptive thread scheduling
23 #include <signal.h>
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
24
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
25 // Reset macros since we're inside state
26 #undef G
27 #undef GO
28 #define G(whatever) globals.whatever.get()
29 #define GO(whatever) globals.whatever
30
d769c944 »
2008-03-25 Initial work on new C++ VM
31 namespace rubinius {
6c31ab68 »
2009-01-05 Add cli switch to enable jit
32 VM::VM(size_t bytes, bool boot)
31ad5c22 »
2009-01-05 Introduces the dynamic interpreter
33 : current_mark(NULL)
34 , reuse_llvm(true)
35 , jit_timing(0)
428c8bec »
2009-01-05 Add switch to enable usage based JIT
36 , jitted_methods(0)
31ad5c22 »
2009-01-05 Introduces the dynamic interpreter
37 , use_safe_position(false)
38 {
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
39 config.compile_up_front = false;
6c31ab68 »
2009-01-05 Add cli switch to enable jit
40 config.jit_enabled = false;
41 config.dynamic_interpreter_enabled = false;
5be79de4 »
2008-08-09 Implement simple context cache
42
1615ead4 »
2008-10-07 Refactoring of ObjectMemory's object creation
43 VM::register_state(this);
44
8dc150ee »
2008-08-14 Implement ConfigParser, wire in into RUBY_CONFIG.
45 user_config = new ConfigParser();
46
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
47 om = new ObjectMemory(this, bytes);
8906a3fb »
2008-09-11 A slew of GC fixes
48 probe.set(Qnil, &globals.roots);
5be79de4 »
2008-08-09 Implement simple context cache
49
6c31ab68 »
2009-01-05 Add cli switch to enable jit
50 if(boot) this->boot();
51 }
52
53 VM::~VM() {
54 delete user_config;
55 delete om;
56 delete signal_events;
57 delete global_cache;
58 #ifdef ENABLE_LLVM
59 if(!reuse_llvm) llvm_cleanup();
60 #endif
61 }
62
63 void VM::boot() {
64 #ifdef USE_USAGE_JIT
65 if(user_config->find("rbx.jit")) {
66 config.jit_enabled = true;
67 }
68 #endif
69
70 #ifdef USE_DYNAMIC_INTERPRETER
71 if(user_config->find("rbx.dyni")) {
72 config.dynamic_interpreter_enabled = true;
73 }
74 #endif
75
5be79de4 »
2008-08-09 Implement simple context cache
76 MethodContext::initialize_cache(this);
5e917ee2 »
2008-12-10 Move TypeInfo::init under ObjectMemory
77 TypeInfo::auto_learn_fields(this);
5be79de4 »
2008-08-09 Implement simple context cache
78
d769c944 »
2008-03-25 Initial work on new C++ VM
79 bootstrap_ontology();
da8639aa »
2008-04-14 Added libev integration. 60% coverage.
80
3f594b6e »
2008-10-19 Changed all TODO:s to @todo so that doxygen picks them up.
81 /* @todo Using a single default loop, revisit when many loops.
82 * @todo This needs to be handled through the environment.
6767c767 »
2008-10-27 disabled EVBACKEND_EPOLL as it seems to make linux unhappy -- this sh…
83 * (disabled epoll backend as it frequently caused hangs on epoll_wait)
d75d4be8 »
2008-10-07 Add forkcheck flag to event loop and init SIGCHLD handler at VM startup.
84 */
6767c767 »
2008-10-27 disabled EVBACKEND_EPOLL as it seems to make linux unhappy -- this sh…
85 signal_events = new event::Loop(EVFLAG_FORKCHECK | EVBACKEND_SELECT | EVBACKEND_POLL);
6163e2fd »
2008-10-03 Fix signal delivery and re-enable SIGINT
86 events = signal_events;
432b29db »
2008-08-27 Get send_on_signal working and couple simple fixes.
87
d75d4be8 »
2008-10-07 Add forkcheck flag to event loop and init SIGCHLD handler at VM startup.
88 signal_events->start(new event::Child::Event(this));
89
9eb47483 »
2008-04-20 Flesh out Task considerable more
90 global_cache = new GlobalCache;
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
91
31ad5c22 »
2009-01-05 Introduces the dynamic interpreter
92 VMMethod::init(this);
93
07cabfc2 »
2008-10-29 Make LLVM optional (and off by default)
94 #ifdef ENABLE_LLVM
569fccd2 »
2008-07-30 Move vm/Rakefile to rakelib/vm.rake, integrate it into the base rake …
95 VMLLVMMethod::init("vm/instructions.bc");
07cabfc2 »
2008-10-29 Make LLVM optional (and off by default)
96 #endif
49d27d7a »
2008-07-14 Move LLVM's lazy code generation into the execute pipeline
97 boot_threads();
f9ec582b »
2008-10-10 Add preemptive thread scheduling
98
99 // Force these back to false because creating the default Thread
100 // sets them to true.
101 interrupts.use_preempt = false;
102 interrupts.enable_preempt = false;
d769c944 »
2008-03-25 Initial work on new C++ VM
103 }
104
bc4b80f3 »
2008-08-26 Remove STATE argument from debug functions
105 // HACK so not thread safe or anything!
106 static VM* __state = NULL;
107
108 VM* VM::current_state() {
109 return __state;
110 }
111
112 void VM::register_state(VM *vm) {
113 __state = vm;
114 }
115
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
116 void VM::boot_threads() {
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
117 Thread* thread = Thread::create(this);
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
118
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
119 thread->sleep(this, Qfalse);
120 globals.current_thread.set(thread);
121 globals.current_task.set(thread->task());
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
122 }
123
78632ae6 »
2008-12-10 Remove using Type::fields infavor of sizeof(Type)
124 Object* VM::new_object_typed(Class* cls, size_t bytes, object_type type) {
125 return om->new_object_typed(cls, bytes, type);
126 }
127
128 Object* VM::new_object_from_type(Class* cls, TypeInfo* ti) {
129 return om->new_object_typed(cls, ti->instance_size, ti->type);
15fc505e »
2008-04-07 More builtin objects, and a README file
130 }
131
e8107bba »
2008-12-10 Remove all traces of ::fields
132 Class* VM::new_basic_class(Class* sup) {
78632ae6 »
2008-12-10 Remove using Type::fields infavor of sizeof(Type)
133 Class *cls = new_object<Class>(G(klass));
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
134 if(sup->nil_p()) {
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
135 cls->instance_type(this, Fixnum::from(ObjectType));
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
136 } else {
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
137 cls->instance_type(this, sup->instance_type()); // HACK test that this is always true
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
138 }
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
139 cls->superclass(this, sup);
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
140
141 return cls;
142 }
143
144 Class* VM::new_class(const char* name) {
e8107bba »
2008-12-10 Remove all traces of ::fields
145 return new_class(name, G(object), G(object));
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
146 }
147
148 Class* VM::new_class(const char* name, Class* super_class) {
e8107bba »
2008-12-10 Remove all traces of ::fields
149 return new_class(name, super_class, G(object));
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
150 }
151
e8107bba »
2008-12-10 Remove all traces of ::fields
152 Class* VM::new_class(const char* name, Class* sup, Module* under) {
153 Class* cls = new_basic_class(sup);
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
154 cls->setup(this, name, under);
155
156 // HACK test that we've got the MOP setup properly
157 MetaClass::attach(this, cls, sup->metaclass(this));
158 return cls;
159 }
160
161 Class* VM::new_class_under(const char* name, Module* under) {
e8107bba »
2008-12-10 Remove all traces of ::fields
162 return new_class(name, G(object), under);
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
163 }
164
165 Module* VM::new_module(const char* name, Module* under) {
78632ae6 »
2008-12-10 Remove using Type::fields infavor of sizeof(Type)
166 Module *mod = new_object<Module>(G(module));
f5cf8333 »
2008-08-23 Reorganize ontology and class initialization
167 mod->setup(this, name, under);
168 return mod;
169 }
170
171
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
172 Symbol* VM::symbol(const char* str) {
5f2adf4c »
2008-08-13 Replaced SymbolTable with native C++ class using STL.
173 return symbols.lookup(this, str);
304caf31 »
2008-04-04 Bunch more work.
174 }
175
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
176 Symbol* VM::symbol(String* str) {
5f2adf4c »
2008-08-13 Replaced SymbolTable with native C++ class using STL.
177 return symbols.lookup(this, str);
195ef1b4 »
2008-08-11 Isolated access to SymbolTable behind VM methods.
178 }
179
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
180 Symbol* VM::symbol(std::string str) {
58105ff1 »
2008-08-14 Added Symbol::all_symbols primitive and fixed up Ruby Symbol code.
181 return symbols.lookup(this, str);
195ef1b4 »
2008-08-11 Isolated access to SymbolTable behind VM methods.
182 }
183
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
184 void type_assert(STATE, Object* obj, object_type type, const char* reason) {
a1704be0 »
2008-10-01 Rework exceptions in the VM.
185 if((obj->reference_p() && obj->obj_type != type)
186 || (type == FixnumType && !obj->fixnum_p())) {
187 Exception::type_error(state, type, obj, reason);
fceff3d8 »
2008-04-09 NativeFunction, Selector, SendSite
188 }
304caf31 »
2008-04-04 Bunch more work.
189 }
4c08cc4b »
2008-04-10 Add object cleanup post collect and on shutdown
190
388b7515 »
2008-05-21 Wire up primitives to be resolved and executed.
191 TypeInfo* VM::find_type(int type) {
192 return om->type_info[type];
193 }
194
f1fa512e »
2008-08-01 Oh yeah, C++ isn't ruby.
195 Thread *VM::current_thread() {
6f546f0c »
2008-08-01 Implement VM::current_thread().
196 return globals.current_thread.get();
da8639aa »
2008-04-14 Added libev integration. 60% coverage.
197 }
f10f1558 »
2008-04-22 Pass in valgrind to find some GC bugs
198
3dc347c4 »
2008-10-28 Fix memory thrash and interrupt checks
199 void VM::run_gc_soon() {
200 om->collect_young_now = true;
201 om->collect_mature_now = true;
202 interrupts.check = true;
203 }
204
f10f1558 »
2008-04-22 Pass in valgrind to find some GC bugs
205 void VM::collect() {
206 om->collect_young(globals.roots);
207 om->collect_mature(globals.roots);
208 }
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
209
f781b6a4 »
2008-10-13 Move GC running into VM, remove Task::check_interrupts
210 void VM::collect_maybe() {
211 if(om->collect_young_now) {
212 om->collect_young_now = false;
213 om->collect_young(globals.roots);
214 global_cache->clear();
215 }
216
217 if(om->collect_mature_now) {
218 om->collect_mature_now = false;
219 om->collect_mature(globals.roots);
220 global_cache->clear();
221 }
222
223 /* Stack Management procedures. Make sure that we don't
224 * miss object stored into the stack of a context */
225 if(G(current_task)->active()->zone == MatureObjectZone) {
226 om->remember_object(G(current_task)->active());
227 }
228
229 if(G(current_task)->home()->zone == MatureObjectZone &&
230 !G(current_task)->home()->Remember) {
231 om->remember_object(G(current_task)->home());
232 }
233 }
234
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
235 bool VM::find_and_activate_thread() {
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
236 Tuple* scheduled = globals.scheduled_threads.get();
237
238 for(std::size_t i = scheduled->num_fields() - 1; i > 0; i--) {
239 List* list = as<List>(scheduled->at(this, i));
240
241 Thread* thread = try_as<Thread>(list->shift(this));
f9ec582b »
2008-10-10 Add preemptive thread scheduling
242
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
243 while(thread) {
244 thread->queued(this, Qfalse);
f9ec582b »
2008-10-10 Add preemptive thread scheduling
245
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
246 /** @todo Should probably try to prevent dead threads here.. */
247 if(thread->alive() == Qfalse) {
248 thread = try_as<Thread>(list->shift(this));
d22ad2d7 »
2008-10-15 Skip over sleeping threads when looking for things to activate.
249 continue;
250 }
251
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
252 if(thread->sleep() == Qtrue) {
253 thread = try_as<Thread>(list->shift(this));
254 continue;
255 }
256
257 activate_thread(thread);
d22ad2d7 »
2008-10-15 Skip over sleeping threads when looking for things to activate.
258 return true;
259 }
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
260 }
261
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
262 return false;
263 }
264
f9ec582b »
2008-10-10 Add preemptive thread scheduling
265 void VM::check_events() {
266 interrupts.check = true;
267 interrupts.check_events = true;
268 }
269
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
270 bool VM::run_best_thread() {
271 events->poll();
272
273 if(!find_and_activate_thread()) {
7e7688eb »
2008-10-07 Fix deadlock detection
274 // It's 1 because the event that looks for SIGCHLD is
275 // always registered.
276 if(events->num_of_events() == 1) {
8a25128b »
2008-08-21 Clean up exception usage.
277 throw DeadLock("no runnable threads, present or future.");
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
278 }
279
f9ec582b »
2008-10-10 Add preemptive thread scheduling
280 interrupts.check_events = true;
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
281 return false;
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
282 }
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
283 return true;
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
284 }
285
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
286 void VM::return_value(Object* val) {
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
287 globals.current_task->push(val);
288 }
289
290 void VM::queue_thread(Thread* thread) {
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
291 if(thread->queued() == Qtrue) {
292 return;
293 }
f9ec582b »
2008-10-10 Add preemptive thread scheduling
294
a1704be0 »
2008-10-01 Rework exceptions in the VM.
295 List* lst = as<List>(globals.scheduled_threads->at(this,
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
296 thread->priority()->to_native()));
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
297 lst->append(this, thread);
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
298
f9ec582b »
2008-10-10 Add preemptive thread scheduling
299 thread->queued(this, Qtrue);
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
300 }
301
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
302 void VM::dequeue_thread(Thread* thread) {
665be9ea »
2008-10-26 Fix minor boo-boo. false != Qfalse..
303 thread->queued(this, Qfalse);
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
304
305 Tuple* scheduled = globals.scheduled_threads.get();
306
307 /** @todo Could it be in more than one somehow? --rue */
308 List* list = try_as<List>(scheduled->at(this, thread->priority()->to_native()));
309 (void) list->remove(this, thread);
310
311 check_events();
312 }
313
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
314 void VM::activate_thread(Thread* thread) {
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
315 if(thread == globals.current_thread.get()) {
665be9ea »
2008-10-26 Fix minor boo-boo. false != Qfalse..
316 thread->task(this, globals.current_task.get());
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
317 return;
318 }
665be9ea »
2008-10-26 Fix minor boo-boo. false != Qfalse..
319
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
320 /* May have been using Tasks directly. */
321 globals.current_thread->task(this, globals.current_task.get());
322 queue_thread(globals.current_thread.get());
323
324 thread->sleep(this, Qfalse);
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
325 globals.current_thread.set(thread);
2cc2e450 »
2008-10-25 Update/fix Thread handling in VM. Possibly over-cautious again.
326
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
327 if(globals.current_task.get() != thread->task()) {
ead72635 »
2008-09-23 Fix the context cache, DRY up some VM code
328 activate_task(thread->task());
ba265dd3 »
2008-08-29 Add proper Task switching, fixes backtrace
329 }
52c078bd »
2008-04-30 Fleshing out Instruction tests, more type safety
330 }
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
331
ead72635 »
2008-09-23 Fix the context cache, DRY up some VM code
332 void VM::activate_task(Task* task) {
333 // Don't try and reclaim any contexts, they belong to someone else.
332ae82b »
2008-10-23 Migrate over the context cache code from shotgun
334 om->clamp_contexts();
ead72635 »
2008-09-23 Fix the context cache, DRY up some VM code
335
336 globals.current_task.set(task);
337 interrupts.check = true;
338 }
339
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
340 Object* VM::current_block() {
387bc2dc »
2008-09-11 Converted to attr_accessor for C++ member variable access.
341 return globals.current_task->active()->block();
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
342 }
343
da078e6f »
2008-08-07 Changed VM::raise_from_errno signature to use const char*.
344 void VM::raise_from_errno(const char* msg) {
3f594b6e »
2008-10-19 Changed all TODO:s to @todo so that doxygen picks them up.
345 // @todo implement me
4f7df71a »
2008-07-28 Added stub for VM::raise_exception.
346 }
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
347
4f7df71a »
2008-07-28 Added stub for VM::raise_exception.
348 void VM::raise_exception(Exception* exc) {
3f594b6e »
2008-10-19 Changed all TODO:s to @todo so that doxygen picks them up.
349 // @todo implement me
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
350 }
351
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
352 void VM::set_const(const char* name, Object* val) {
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
353 globals.object->set_const(this, (char*)name, val);
354 }
879a0469 »
2008-05-15 A whole slew. Enhanced type-info, debugged GC.
355
1fdd151d »
2008-10-19 Changed all OBJECT, SYMBOL, FIXNUM, INTEGER to normal syntax.
356 void VM::set_const(Module* mod, const char* name, Object* val) {
feb91b43 »
2008-05-07 Tons of stuff (too much probably)
357 mod->set_const(this, (char*)name, val);
358 }
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
359
360 void VM::print_backtrace() {
eea8ecc9 »
2008-08-28 Move print_backtrace() to Task, fix rbt on Thread switch
361 globals.current_task.get()->print_backtrace();
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
362 }
363
364 Task* VM::new_task() {
365 Task* task = Task::create(this);
ead72635 »
2008-09-23 Fix the context cache, DRY up some VM code
366 activate_task(task);
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
367 return task;
368 }
369
31ad5c22 »
2009-01-05 Introduces the dynamic interpreter
370 void VM::raise_exception_safely(Exception* exc) {
371 safe_position_data.exc = exc;
372 siglongjmp(safe_position, cReasonException);
373 // Never reached.
374 }
375
376 void VM::raise_typeerror_safely(TypeError* err) {
377 safe_position_data.type_error = err;
378 siglongjmp(safe_position, cReasonTypeError);
379 // Never reached.
380 }
381
382 void VM::raise_assertion_safely(Assertion* err) {
383 safe_position_data.assertion = err;
384 siglongjmp(safe_position, cReasonAssertion);
385 // Never reached.
386 }
387
ba265dd3 »
2008-08-29 Add proper Task switching, fixes backtrace
388 void VM::run_and_monitor() {
31ad5c22 »
2009-01-05 Introduces the dynamic interpreter
389 int reason;
390
391 use_safe_position = true;
392 reason = sigsetjmp(safe_position, 0);
393 // If reason is not 0, then we're here because of a longjmp.
394 if(reason) {
395 switch(reason) {
396 case cReasonException:
397 G(current_task)->raise_exception(safe_position_data.exc);
398 break;
399 case cReasonTypeError: {
400 TypeError* exc = safe_position_data.type_error;
401 Exception* e = Exception::make_type_error(this, exc->type, exc->object, exc->reason);
402 G(current_task)->raise_exception(e);
403 delete exc;
404 safe_position_data.type_error = NULL;
405 break;
406 }
407 case cReasonAssertion:
408 throw safe_position_data.assertion;
409
410 default:
411 break;
412 // We're not sure what this is. Oh well, hopefully the longjmp
413 // user knew what they were doing.
414 }
415 }
416
ba265dd3 »
2008-08-29 Add proper Task switching, fixes backtrace
417 for(;;) {
f9ec582b »
2008-10-10 Add preemptive thread scheduling
418 if(interrupts.check_events) {
419 interrupts.check_events = false;
420 interrupts.enable_preempt = false;
421
422 Thread* current = G(current_thread);
423 // The current thread isn't asleep, so we're being preemptive
424 if(current->alive() == Qtrue && current->sleep() != Qtrue) {
425 // Order is important here. We poll so any threads
426 // might get woken up if they need to be.
427 events->poll();
428
429 // Only then do we reschedule the current thread if
430 // we need to. queue_thread() puts the thread at the end
431 // of the list for it's priority, so we shouldn't starve
432 // anything this way.
433 queue_thread(G(current_thread));
434 }
435
436 while(!find_and_activate_thread()) {
437 events->run_and_wait();
438 }
439
440 interrupts.enable_preempt = interrupts.use_preempt;
719c98f5 »
2008-10-03 Fix Thread and Channel to interact properly
441 }
442
f781b6a4 »
2008-10-13 Move GC running into VM, remove Task::check_interrupts
443 collect_maybe();
ba265dd3 »
2008-08-29 Add proper Task switching, fixes backtrace
444 G(current_task)->execute();
445 }
446 }
447
f9ec582b »
2008-10-10 Add preemptive thread scheduling
448 // Trampoline to call scheduler_loop()
449 static void* __thread_tramp__(void* arg) {
450 VM* state = static_cast<VM*>(arg);
451 state->scheduler_loop();
452 return NULL;
453 }
454
455 // Create the preemption thread and call scheduler_loop() in the new thread
456 void VM::setup_preemption() {
457 if(pthread_create(&preemption_thread, NULL, __thread_tramp__, this) != 0) {
458 std::cout << "Unable to create preemption thread!\n";
459 }
460 }
461
462 // Runs forever, telling the VM to reschedule threads ever 10 milliseconds
463 void VM::scheduler_loop() {
464 // First off, we don't want this thread ever receiving a signal.
465 sigset_t mask;
466 sigfillset(&mask);
467 if(pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0) {
468 abort();
469 }
470
471 struct timespec requested;
472 struct timespec actual;
473
474 requested.tv_sec = 0;
475 requested.tv_nsec = 10000000; // 10 milliseconds
476
477 for(;;) {
478 nanosleep(&requested, &actual);
479 if(interrupts.enable_preempt) {
480 interrupts.reschedule = true;
481 interrupts.check_events = true;
482 }
483 }
484 }
485
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
486 /* For debugging. */
487 extern "C" {
bc4b80f3 »
2008-08-26 Remove STATE argument from debug functions
488 void __printbt__() {
489 VM::current_state()->print_backtrace();
310a461d »
2008-08-07 Cleanup stack usage and fix interpreter
490 }
491 }
d769c944 »
2008-03-25 Initial work on new C++ VM
492 };
Something went wrong with that request. Please try again.