Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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