// Expand or shrink a chunk returned by allocate_chunk(). // The chunk is never moved. // // Returns 0 if fail to expand (shrink will always succeed). Returns old // size if successful. size_t OsMemory_adjust_chunk(address chunk_ptr, size_t new_committed_size) { ChunkInfo* ci = get_chunk_info(chunk_ptr); size_t old_size = ci->size; size_t new_size = page_align_up(new_committed_size); if (new_size <= ci->mmaped_size) { int rv; if (new_size < old_size) { rv = protect_area(chunk_ptr + new_size, old_size - new_size); } else { rv = unprotect_area(chunk_ptr, new_size); } GUARANTEE(rv == 0, "mprotect must succeed"); ci->size = new_size; return old_size; } new_size = page_align_up(new_size - ci->mmaped_size); if (anon_mmap(chunk_ptr + ci->mmaped_size, new_size) == NULL) { return 0; } ci->mmaped_size += new_size; ci->size = ci->mmaped_size; unprotect_area(chunk_ptr, ci->size); return old_size; }
address OsMemory_allocate_chunk(size_t initial_size, size_t max_size, size_t alignment) { // make it page aligned max_size = page_align_up(max_size); address chunk = anon_mmap(NULL, max_size); if (chunk == MAP_FAILED) { return NULL; } GUARANTEE((juint)chunk % alignment == 0, "must be aligned"); GUARANTEE((juint)chunk % SysPageSize == 0, "must be page aligned"); size_t aligned_size = page_align_up(initial_size); alloc_chunk(chunk, aligned_size, max_size); if (max_size > aligned_size) { protect_area(chunk + aligned_size, max_size - aligned_size); } return chunk; }
/* 0: bad, 1: Ok */ int check_for_ptr (char *ptr, int fd_file) { int res; caddr_t addr; /* An available area must not be busy. */ res = write (fd_file, ptr, 8); if (res == -1) { if (errno != EFAULT) buggy_os (); } else { /* Success: this mean that the memory is already used. */ return 0; /* Don't touch. */ } /* An available area must be usuable. */ addr = anon_mmap (ptr, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED); if (addr == (caddr_t) -1) return 0; res = setjmp (env); if (res == 0) { /* Now, test it. */ *(volatile char *)addr += 1; munmap (addr, pagesize); return 1; } else { SPAM2(1, "Received signal %d at addr = 0x%08x\n", res, (unsigned)addr); munmap (addr, pagesize); set_sig_handler (); return 0; } return 1; }