Esempio n. 1
0
// 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;
}
Esempio n. 2
0
/** Records code chunk, corresponding to longest prefix of instruction sequence,
 *  into buffer [current, end). Changes _instr_ to instruction immediately
 *  following prefix. Returns next position in the buffer, or NULL if there is
 *  not enough space. */
void* record_chunk(void* ctx, instr_t** instr, void* current, void* end) {
  struct code_chunk_t* chunk;
  ssize_t max;
  struct chunk_info_t chunk_info;

  chunk = current;
  max = end - current - sizeof(struct code_chunk_t);
  if(max <= 0) {
    return NULL;
  }
  if(max > UINT8_MAX) {
    max = UINT8_MAX;
  }
  chunk_info = get_chunk_info(ctx, instr, max);
  if(chunk_info.size == 0) {
    return NULL;
  }
  chunk->pc = (uintptr_t)chunk_info.pc;
  chunk->size = (uint8_t)chunk_info.size;
  memcpy(chunk->code, chunk_info.pc, chunk_info.size);
  return &chunk->code[chunk_info.size];
}
Esempio n. 3
0
void OsMemory_free_chunk(address chunk_ptr) {
  ChunkInfo* ci = get_chunk_info(chunk_ptr);
  jvm_munmap(ci->addr, ci->mmaped_size);
  release_chunk(chunk_ptr);
}