static LLVMTypeRef send_message(compile_t* c, ast_t* fun, LLVMValueRef to, LLVMValueRef func, uint32_t index) { // Get the parameter types. LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(func)); int count = LLVMCountParamTypes(f_type) + 2; VLA(LLVMTypeRef, f_params, count); LLVMGetParamTypes(f_type, &f_params[2]); // The first one becomes the message size, the second the message ID. f_params[0] = c->i32; f_params[1] = c->i32; f_params[2] = c->void_ptr; LLVMTypeRef msg_type = LLVMStructTypeInContext(c->context, f_params, count, false); LLVMTypeRef msg_type_ptr = LLVMPointerType(msg_type, 0); // Allocate the message, setting its size and ID. size_t msg_size = LLVMABISizeOfType(c->target_data, msg_type); LLVMValueRef args[2]; args[0] = LLVMConstInt(c->i32, pool_index(msg_size), false); args[1] = LLVMConstInt(c->i32, index, false); LLVMValueRef msg = gencall_runtime(c, "pony_alloc_msg", args, 2, ""); LLVMValueRef msg_ptr = LLVMBuildBitCast(c->builder, msg, msg_type_ptr, ""); // Trace while populating the message contents. LLVMValueRef start_trace = gencall_runtime(c, "pony_gc_send", NULL, 0, ""); ast_t* params = ast_childidx(fun, 3); ast_t* param = ast_child(params); bool need_trace = false; for(int i = 3; i < count; i++) { LLVMValueRef arg = LLVMGetParam(func, i - 2); LLVMValueRef arg_ptr = LLVMBuildStructGEP(c->builder, msg_ptr, i, ""); LLVMBuildStore(c->builder, arg, arg_ptr); need_trace |= gentrace(c, arg, ast_type(param)); param = ast_sibling(param); } if(need_trace) gencall_runtime(c, "pony_send_done", NULL, 0, ""); else LLVMInstructionEraseFromParent(start_trace); // Send the message. args[0] = LLVMBuildBitCast(c->builder, to, c->object_ptr, ""); args[1] = msg; gencall_runtime(c, "pony_sendv", args, 2, ""); // Return the type of the message. return msg_type_ptr; }
static PyObject *HoseIndex (HoseObject *self, PyObject *args) { if (! PyArg_ParseTuple (args, "")) { return NULL; } ob_retort ret; int64 index; ret = pool_index (self->hose, &index); PYTHON_OBCHECK (ret); return PyLong_FromLong (index); }
void pool_free_size(size_t size, void* p) { size_t index = pool_index(size); if(index < POOL_COUNT) return pool_free(index, p); virtual_free(p, size); #ifdef USE_VALGRIND VALGRIND_FREELIKE_BLOCK(p, 0); #endif }
void* pool_alloc_size(size_t size) { size_t index = pool_index(size); void* p; if(index < POOL_COUNT) return pool_alloc(index); // p = pool_get(index); // else p = virtual_alloc(size); #ifdef USE_VALGRIND VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0); #endif return p; }
void pool_free_size(size_t size, void* p) { size_t index = pool_index(size); if(index < POOL_COUNT) return pool_free(index, p); #ifdef USE_VALGRIND VALGRIND_DISABLE_ERROR_REPORTING; #endif size = pool_adjust_size(size); pool_free_pages(p, size); TRACK_FREE(p, size); #ifdef USE_VALGRIND VALGRIND_ENABLE_ERROR_REPORTING; VALGRIND_FREELIKE_BLOCK(p, 0); #endif }
void* pool_alloc_size(size_t size) { size_t index = pool_index(size); if(index < POOL_COUNT) return pool_alloc(index); #ifdef USE_VALGRIND VALGRIND_DISABLE_ERROR_REPORTING; #endif size = pool_adjust_size(size); void* p = pool_alloc_pages(size); TRACK_ALLOC(p, size); #ifdef USE_VALGRIND VALGRIND_ENABLE_ERROR_REPORTING; VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0); #endif return p; }
static void gen_main(compile_t* c, gentype_t* main_g, gentype_t* env_g) { LLVMTypeRef params[3]; params[0] = c->i32; params[1] = LLVMPointerType(LLVMPointerType(c->i8, 0), 0); params[2] = LLVMPointerType(LLVMPointerType(c->i8, 0), 0); LLVMTypeRef ftype = LLVMFunctionType(c->i32, params, 3, false); LLVMValueRef func = LLVMAddFunction(c->module, "main", ftype); codegen_startfun(c, func, false); LLVMValueRef args[3]; args[0] = LLVMGetParam(func, 0); LLVMSetValueName(args[0], "argc"); args[1] = LLVMGetParam(func, 1); LLVMSetValueName(args[1], "argv"); args[2] = LLVMGetParam(func, 2); LLVMSetValueName(args[1], "envp"); // Initialise the pony runtime with argc and argv, getting a new argc. args[0] = gencall_runtime(c, "pony_init", args, 2, "argc"); // Create the main actor and become it. LLVMValueRef main_actor = create_main(c, main_g); // Create an Env on the main actor's heap. const char* env_name = "Env"; const char* env_create = genname_fun(env_name, "_create", NULL); LLVMValueRef env_args[4]; env_args[0] = gencall_alloc(c, env_g); env_args[1] = LLVMBuildZExt(c->builder, args[0], c->i64, ""); env_args[2] = args[1]; env_args[3] = args[2]; LLVMValueRef env = gencall_runtime(c, env_create, env_args, 4, "env"); LLVMSetInstructionCallConv(env, GEN_CALLCONV); // Run primitive initialisers using the main actor's heap. primitive_call(c, stringtab("_init"), env); // Create a type for the message. LLVMTypeRef f_params[4]; f_params[0] = c->i32; f_params[1] = c->i32; f_params[2] = c->void_ptr; f_params[3] = LLVMTypeOf(env); LLVMTypeRef msg_type = LLVMStructTypeInContext(c->context, f_params, 4, false); LLVMTypeRef msg_type_ptr = LLVMPointerType(msg_type, 0); // Allocate the message, setting its size and ID. uint32_t index = genfun_vtable_index(c, main_g, stringtab("create"), NULL); size_t msg_size = LLVMABISizeOfType(c->target_data, msg_type); args[0] = LLVMConstInt(c->i32, pool_index(msg_size), false); args[1] = LLVMConstInt(c->i32, index, false); LLVMValueRef msg = gencall_runtime(c, "pony_alloc_msg", args, 2, ""); LLVMValueRef msg_ptr = LLVMBuildBitCast(c->builder, msg, msg_type_ptr, ""); // Set the message contents. LLVMValueRef env_ptr = LLVMBuildStructGEP(c->builder, msg_ptr, 3, ""); LLVMBuildStore(c->builder, env, env_ptr); // Trace the message. gencall_runtime(c, "pony_gc_send", NULL, 0, ""); const char* env_trace = genname_trace(env_name); args[0] = LLVMBuildBitCast(c->builder, env, c->object_ptr, ""); args[1] = LLVMGetNamedFunction(c->module, env_trace); gencall_runtime(c, "pony_traceobject", args, 2, ""); gencall_runtime(c, "pony_send_done", NULL, 0, ""); // Send the message. args[0] = main_actor; args[1] = msg; gencall_runtime(c, "pony_sendv", args, 2, ""); // Start the runtime. LLVMValueRef zero = LLVMConstInt(c->i32, 0, false); LLVMValueRef rc = gencall_runtime(c, "pony_start", &zero, 1, ""); // Run primitive finalisers. We create a new main actor as a context to run // the finalisers in, but we do not initialise or schedule it. LLVMValueRef final_actor = create_main(c, main_g); primitive_call(c, stringtab("_final"), NULL); args[0] = final_actor; gencall_runtime(c, "pony_destroy", args, 1, ""); // Return the runtime exit code. LLVMBuildRet(c->builder, rc); codegen_finishfun(c); // External linkage for main(). LLVMSetLinkage(func, LLVMExternalLinkage); }
BasicType Bytecode_loadconstant::result_type() const { int index = pool_index(); constantTag tag = _method->constants()->tag_at(index); return tag.basic_type(); }