コード例 #1
0
ファイル: gencall.c プロジェクト: killerswan/ponyc
LLVMValueRef gencall_allocstruct(compile_t* c, reach_type_t* t)
{
  // We explicitly want a boxed version.
  // Allocate the object.
  LLVMValueRef args[3];
  args[0] = codegen_ctx(c);

  LLVMValueRef result;

  size_t size = t->abi_size;
  if(size == 0)
    size = 1;

  if(size <= HEAP_MAX)
  {
    uint32_t index = ponyint_heap_index(size);
    args[1] = LLVMConstInt(c->i32, index, false);
    if(t->final_fn == NULL)
      result = gencall_runtime(c, "pony_alloc_small", args, 2, "");
    else
      result = gencall_runtime(c, "pony_alloc_small_final", args, 2, "");
  } else {
    args[1] = LLVMConstInt(c->intptr, size, false);
    if(t->final_fn == NULL)
      result = gencall_runtime(c, "pony_alloc_large", args, 2, "");
    else
      result = gencall_runtime(c, "pony_alloc_large_final", args, 2, "");
  }

  result = LLVMBuildBitCast(c->builder, result, t->structure_ptr, "");
  set_descriptor(c, t, result);

  return result;
}
コード例 #2
0
void* ponyint_heap_realloc(pony_actor_t* actor, heap_t* heap, void* p,
  size_t size)
{
  if(p == NULL)
    return ponyint_heap_alloc(actor, heap, size);

  chunk_t* chunk = (chunk_t*)ponyint_pagemap_get(p);

  if(chunk == NULL)
  {
    // Get new memory and copy from the old memory.
    void* q = ponyint_heap_alloc(actor, heap, size);
    memcpy(q, p, size);
    return q;
  }

  size_t oldsize;

  if(chunk->size < HEAP_SIZECLASSES)
  {
    // Previous allocation was a ponyint_heap_alloc_small.
    void* ext = EXTERNAL_PTR(p, chunk->size);

    // If the new allocation is a ponyint_heap_alloc_small and the pointer is
    // not an internal pointer, we may be able to reuse this memory. If it is
    // an internal pointer, we know where the old allocation begins but not
    // where it ends, so we cannot reuse this memory.
    if((size <= HEAP_MAX) && (p == ext))
    {
      uint32_t sizeclass = ponyint_heap_index(size);

      // If the new allocation is the same size or smaller, return the old
      // one.
      if(sizeclass <= chunk->size)
        return p;
    }

    oldsize = SIZECLASS_SIZE(chunk->size) - ((uintptr_t)p - (uintptr_t)ext);
  } else {
    // Previous allocation was a ponyint_heap_alloc_large.
    if((size <= chunk->size) && (p == chunk->m))
    {
      // If the new allocation is the same size or smaller, and this is not an
      // internal pointer, return the old one. We can't reuse internal
      // pointers in large allocs for the same reason as small ones.
      return p;
    }

    oldsize = chunk->size - ((uintptr_t)p - (uintptr_t)chunk->m);
  }

  // Determine how much memory to copy.
  if(oldsize > size)
    oldsize = size;

  // Get new memory and copy from the old memory.
  void* q = ponyint_heap_alloc(actor, heap, size);
  memcpy(q, p, oldsize);
  return q;
}
コード例 #3
0
ファイル: heap.c プロジェクト: JamesLinus/ponyc
void* ponyint_heap_alloc(pony_actor_t* actor, heap_t* heap, size_t size)
{
  if(size == 0)
  {
    return NULL;
  } else if(size <= HEAP_MAX) {
    return ponyint_heap_alloc_small(actor, heap, ponyint_heap_index(size));
  } else {
    return ponyint_heap_alloc_large(actor, heap, size);
  }
}
コード例 #4
0
ファイル: gencall.c プロジェクト: cyisfor/ponyc
LLVMValueRef gencall_allocstruct(compile_t* c, gentype_t* g)
{
  // Disable debug anchor
  dwarf_location(&c->dwarf, NULL);

  // We explicitly want a boxed version.
  // Get the size of the structure.
  size_t size = (size_t)LLVMABISizeOfType(c->target_data, g->structure);

  // Get the finaliser, if there is one.
  const char* final = genname_finalise(g->type_name);
  LLVMValueRef final_fun = LLVMGetNamedFunction(c->module, final);

  // Allocate the object.
  LLVMValueRef args[3];
  args[0] = codegen_ctx(c);

  LLVMValueRef result;

  if(final_fun == NULL)
  {
    if(size <= HEAP_MAX)
    {
      uint32_t index = ponyint_heap_index(size);
      args[1] = LLVMConstInt(c->i32, index, false);
      result = gencall_runtime(c, "pony_alloc_small", args, 2, "");
    } else {
      args[1] = LLVMConstInt(c->intptr, size, false);
      result = gencall_runtime(c, "pony_alloc_large", args, 2, "");
    }
  } else {
    args[1] = LLVMConstInt(c->intptr, size, false);
    args[2] = LLVMConstBitCast(final_fun, c->final_fn);
    result = gencall_runtime(c, "pony_alloc_final", args, 3, "");
  }

  result = LLVMBuildBitCast(c->builder, result, g->structure_ptr, "");

  // Set the descriptor.
  if(g->underlying != TK_STRUCT)
  {
    LLVMValueRef desc_ptr = LLVMBuildStructGEP(c->builder, result, 0, "");
    LLVMBuildStore(c->builder, g->desc, desc_ptr);
  }

  return result;
}
コード例 #5
0
ファイル: heap.c プロジェクト: JamesLinus/ponyc
void* ponyint_heap_realloc(pony_actor_t* actor, heap_t* heap, void* p,
  size_t size)
{
  if(p == NULL)
    return ponyint_heap_alloc(actor, heap, size);

  chunk_t* chunk = (chunk_t*)ponyint_pagemap_get(p);

  if(chunk == NULL)
  {
    // Get new memory and copy from the old memory.
    void* q = ponyint_heap_alloc(actor, heap, size);
    memcpy(q, p, size);
    return q;
  }

  if(chunk->size < HEAP_SIZECLASSES)
  {
    // Previous allocation was a ponyint_heap_alloc_small.
    if(size <= HEAP_MAX)
    {
      uint32_t sizeclass = ponyint_heap_index(size);

      // If the new allocation is the same size or smaller, return the old one.
      if(sizeclass <= chunk->size)
        return p;
    }

    // Get new memory and copy from the old memory.
    void* q = ponyint_heap_alloc(actor, heap, size);
    memcpy(q, p, SIZECLASS_SIZE(chunk->size));
    return q;
  }

  // Previous allocation was a ponyint_heap_alloc_large.
  if(size <= chunk->size)
    return p;

  // Get new memory and copy from the old memory.
  void* q = ponyint_heap_alloc(actor, heap, size);
  memcpy(q, p, chunk->size);
  return q;
}