void BlockEnvironment::Info::show(STATE, Object* self, int level) { BlockEnvironment* be = as<BlockEnvironment>(self); class_header(state, self); //indent_attribute(++level, "scope"); be->scope()->show(state, level); // indent_attribute(level, "top_scope"); be->top_scope()->show(state, level); indent_attribute(level, "compiled_code"); be->compiled_code()->show(state, level); close_body(level); }
BlockEnvironment* BlockEnvironment::dup(STATE) { BlockEnvironment* be = state->new_object<BlockEnvironment>(G(blokenv)); be->scope(state, scope_); be->top_scope(state, top_scope_); be->code(state, code_); return be; }
BlockEnvironment* BlockEnvironment::dup(STATE) { BlockEnvironment* be = state->new_object_dirty<BlockEnvironment>(G(blokenv)); be->scope(state, scope_); be->top_scope(state, top_scope_); be->compiled_code(state, compiled_code_); be->module(state, nil<Module>()); return be; }
void BlockEnvironment::Info::show(STATE, Object* self, int level) { BlockEnvironment* be = as<BlockEnvironment>(self); class_header(state, self); indent_attribute(++level, "home"); be->home()->show(state, level); indent_attribute(level, "home_block"); be->home_block()->show(state, level); indent_attribute(level, "local_count"); be->local_count()->show(state, level); indent_attribute(level, "method"); be->method()->show(state, level); close_body(level); }
BlockEnvironment* BlockEnvironment::dup(STATE) { BlockEnvironment* be = state->new_object<BlockEnvironment>(G(blokenv)); be->execute = &BlockEnvironment::execute_interpreter; be->scope(state, scope_); be->top_scope(state, top_scope_); be->method(state, method_); be->local_count(state, local_count_); be->vmm = this->vmm; return be; }
BlockEnvironment* BlockEnvironment::under_call_frame(STATE, CompiledMethod* cm, VMMethod* caller, CallFrame* call_frame, size_t index) { BlockEnvironment* be = state->new_object<BlockEnvironment>(G(blokenv)); VMMethod* vmm = cm->internalize(state); if(!vmm) { Exception::internal_error(state, call_frame, "invalid bytecode method"); return 0; } vmm->set_parent(caller); be->scope(state, call_frame->promote_scope(state)); be->top_scope(state, call_frame->top_scope(state)); be->code(state, cm); be->module(state, call_frame->module()); return be; }
BlockEnvironment* BlockEnvironment::under_call_frame(STATE, CompiledMethod* cm, VMMethod* caller, CallFrame* call_frame, size_t index) { BlockEnvironment* be = state->new_object<BlockEnvironment>(G(blokenv)); VMMethod* vmm = caller->blocks.at(index); if(!vmm) { vmm = cm->formalize(state); if(caller->type) { vmm->specialize(state, caller->type); } caller->blocks[index] = vmm; vmm->set_parent(caller); } be->scope(state, call_frame->promote_scope(state)); be->top_scope(state, call_frame->top_scope(state)); be->method(state, cm); be->module(state, call_frame->module()); be->local_count(state, cm->local_count()); be->vmm = vmm; BlockExecutor native = reinterpret_cast<BlockExecutor>(vmm->native_function); if(native) { be->execute = native; } else { be->execute = &BlockEnvironment::execute_interpreter; } return be; }
BlockEnvironment* BlockEnvironment::under_call_frame(STATE, CompiledCode* ccode, MachineCode* caller) { MachineCode* mcode = ccode->machine_code(); if(!mcode) { OnStack<1> os(state, ccode); mcode = ccode->internalize(state); if(!mcode) { Exception::internal_error(state, "invalid bytecode method"); return 0; } } BlockEnvironment* be = state->memory()->new_object<BlockEnvironment>(state, G(blokenv)); CallFrame* call_frame = state->vm()->call_frame(); be->scope(state, call_frame->promote_scope(state)); be->top_scope(state, call_frame->top_scope(state)); be->compiled_code(state, ccode); be->constant_scope(state, call_frame->constant_scope()); be->module(state, call_frame->module()); return be; }
BlockEnvironment* BlockEnvironment::under_call_frame(STATE, GCToken gct, CompiledCode* ccode, MachineCode* caller, CallFrame* call_frame) { MachineCode* mcode = ccode->machine_code(); if(!mcode) { OnStack<1> os(state, ccode); state->set_call_frame(call_frame); mcode = ccode->internalize(state, gct); if(!mcode) { Exception::internal_error(state, call_frame, "invalid bytecode method"); return 0; } } mcode->set_parent(caller); BlockEnvironment* be = state->new_object_dirty<BlockEnvironment>(G(blokenv)); be->scope(state, call_frame->promote_scope(state)); be->top_scope(state, call_frame->top_scope(state)); be->compiled_code(state, ccode); be->module(state, call_frame->module()); be->metadata_container(state, nil<Tuple>()); return be; }
BlockEnvironment* BlockEnvironment::under_context(STATE, CompiledMethod* cm, MethodContext* parent, MethodContext* active, size_t index) { BlockEnvironment* be = (BlockEnvironment*)state->new_object(G(blokenv)); VMMethod* vmm; if((vmm = active->vmm->blocks[index]) == NULL) { vmm = new VMMethod(state, cm); if(active->vmm->type) { vmm->specialize(state, active->vmm->type); } active->vmm->blocks[index] = vmm; } be->home(state, parent); be->home_block(state, active); be->method(state, cm); be->local_count(state, cm->local_count()); be->vmm = vmm; return be; }
BlockEnvironment* BlockEnvironment::dup(STATE) { BlockEnvironment* be = state->memory()->new_object<BlockEnvironment>(state, G(blokenv)); be->scope(state, scope()); be->top_scope(state, top_scope()); be->compiled_code(state, compiled_code()); be->constant_scope(state, constant_scope()); be->module(state, nil<Module>()); return be; }
virtual void perform() { for(;;) { // forever BackgroundCompileRequest* req = 0; // Lock, wait, get a request, unlock { thread::Mutex::LockGuard guard(mutex_); if(pause_) { state = cPaused; paused_ = true; pause_condition_.signal(); while(pause_) { condition_.wait(mutex_); } state = cUnknown; paused_ = false; } // If we've been asked to stop, do so now. if(stop_) return; while(pending_requests_.size() == 0) { state = cIdle; // unlock and wait... condition_.wait(mutex_); if(stop_) return; } // now locked again, shift a request req = pending_requests_.front(); pending_requests_.pop_front(); state = cRunning; } // mutex now unlock, allowing others to push more requests // LLVMCompiler* jit = new LLVMCompiler(); { timer::Running timer(ls_->time_spent); jit->compile(ls_, req->vmmethod(), req->is_block()); jit->generate_function(ls_); } if(show_machine_code_) { jit->show_machine_code(); } // Ok, compiled, generated machine code, now update MachineMethod // Ok, now we are manipulating managed memory, so make // sure the GC doesn't run. ls_->shared().gc_dependent(); req->vmmethod()->set_jitted(jit->llvm_function(), jit->code_bytes(), jit->function_pointer()); if(req->is_block()) { BlockEnvironment* be = req->block_env(); if(!be) { llvm::outs() << "Fatal error in JIT. Expected a BlockEnvironment.\n"; } else { be->set_native_function(jit->function_pointer()); } } else { MachineMethod* mm = req->machine_method(); if(!mm) { llvm::outs() << "Fatal error in JIT. Expected a MachineMethod.\n"; } else { mm->update(req->vmmethod(), jit); mm->activate(); } } int which = ls_->add_jitted_method(); if(ls_->config().jit_show_compiling) { llvm::outs() << "[[[ JIT finished background compiling " << which << (req->is_block() ? " (block)" : " (method)") << " ]]]\n"; } delete req; // We don't depend on the GC here, so let it run independent // of us. ls_->shared().gc_independent(); } }