// // Method: getObjectSize() // // Description: // Try to get an LLVM value that represents the size of the memory object // referenced by the specified pointer. // Value * AllocatorInfoPass::getObjectSize(Value * V) { // Get access to the target data information TargetData & TD = getAnalysis<TargetData>(); // // Finding the size of a global variable is easy. // Type * Int32Type = IntegerType::getInt32Ty(V->getContext()); if (GlobalVariable * GV = dyn_cast<GlobalVariable>(V)) { Type * allocType = GV->getType()->getElementType(); return ConstantInt::get (Int32Type, TD.getTypeAllocSize (allocType)); } // // Find the size of byval function arguments is also easy. // if (Argument * AI = dyn_cast<Argument>(V)) { if (AI->hasByValAttr()) { assert (isa<PointerType>(AI->getType())); PointerType * PT = cast<PointerType>(AI->getType()); unsigned int type_size = TD.getTypeAllocSize (PT->getElementType()); return ConstantInt::get (Int32Type, type_size); } } // // Alloca instructions are a little harder but not bad. // if (AllocaInst * AI = dyn_cast<AllocaInst>(V)) { unsigned int type_size = TD.getTypeAllocSize (AI->getAllocatedType()); if (AI->isArrayAllocation()) { if (ConstantInt * CI = dyn_cast<ConstantInt>(AI->getArraySize())) { if (CI->getSExtValue() > 0) { type_size *= CI->getSExtValue(); } else { return NULL; } } else { return NULL; } } return ConstantInt::get(Int32Type, type_size); } // // Heap (i.e., customized) allocators are the most difficult, but we can // manage. // if (CallInst * CI = dyn_cast<CallInst>(V)) { Function * F = CI->getCalledFunction(); if (!F) return NULL; const std::string & name = F->getName(); for (alloc_iterator it = alloc_begin(); it != alloc_end(); ++it) { if ((*it)->isAllocSizeMayConstant(CI) && (*it)->getAllocCallName() == name) { return (*it)->getAllocSize(CI); } } } return NULL; }
struct ilka_region * ilka_open(const char *file, struct ilka_options *options) { journal_recover(file); struct ilka_region *r = calloc(1, sizeof(struct ilka_region)); if (!r) { ilka_fail("out-of-memory for ilka_region struct: %lu", sizeof(struct ilka_region)); return NULL; } slock_init(&r->lock); r->file = file; r->options = *options; if ((r->fd = file_open(file, &r->options)) == -1) goto fail_open; if ((r->len = file_grow(r->fd, ILKA_PAGE_SIZE)) == -1UL) goto fail_grow; if (!mmap_init(&r->mmap, r->fd, r->len, &r->options)) goto fail_mmap; if (!persist_init(&r->persist, r, r->file)) goto fail_persist; const struct meta * meta = meta_read(r); if (meta->magic != ilka_magic) { if (!r->options.create) { ilka_fail("invalid magic for file '%s'", file); goto fail_magic; } struct meta * m = meta_write(r); m->magic = ilka_magic; m->version = ilka_version; m->alloc = sizeof(struct meta); } if (meta->version != ilka_version) { ilka_fail("invalid version for file '%s': %lu != %lu", file, meta->version, ilka_version); goto fail_version; } if (!alloc_init(&r->alloc, r, &r->options, meta->alloc)) goto fail_alloc; if (!epoch_init(&r->epoch, r, &r->options)) goto fail_epoch; if (ILKA_MCHECK) mcheck_init(&r->mcheck); r->header_len = alloc_end(&r->alloc); return r; fail_epoch: fail_alloc: fail_version: fail_magic: persist_close(&r->persist); fail_persist: mmap_close(&r->mmap); fail_mmap: fail_grow: file_close(r->fd); fail_open: free(r); return NULL; }