Exemplo n.º 1
0
VarCell* Context::_newStackCell(uint32_t size, uint32_t alignment) {
  VarCell* cell = static_cast<VarCell*>(_zoneAllocator.alloc(sizeof(VarCell)));
  if (cell == nullptr)
    goto _NoMemory;

  if (alignment == 0)
    alignment = BaseContext_getDefaultAlignment(size);

  if (alignment > 64)
    alignment = 64;

  ASMJIT_ASSERT(Utils::isPowerOf2(alignment));
  size = Utils::alignTo<uint32_t>(size, alignment);

  // Insert it sorted according to the alignment and size.
  {
    VarCell** pPrev = &_memStackCells;
    VarCell* cur = *pPrev;

    while (cur != nullptr) {
      if ((cur->getAlignment() > alignment) ||
          (cur->getAlignment() == alignment && cur->getSize() > size)) {
        pPrev = &cur->_next;
        cur = *pPrev;
        continue;
      }

      break;
    }

    cell->_next = cur;
    cell->_offset = 0;
    cell->_size = size;
    cell->_alignment = alignment;

    *pPrev = cell;
    _memStackCellsUsed++;

    _memMaxAlign = Utils::iMax<uint32_t>(_memMaxAlign, alignment);
    _memStackTotal += size;
  }

  return cell;

_NoMemory:
  _compiler->setLastError(kErrorNoHeapMemory);
  return nullptr;
}
Exemplo n.º 2
0
Error Context::resolveCellOffsets() {
  VarCell* varCell = _memVarCells;
  VarCell* stackCell = _memStackCells;

  uint32_t stackAlignment = 0;
  if (stackCell != nullptr)
    stackAlignment = stackCell->getAlignment();

  uint32_t pos64 = 0;
  uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
  uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
  uint32_t pos8  = pos16 + _mem16ByteVarsUsed * 16;
  uint32_t pos4  = pos8  + _mem8ByteVarsUsed  * 8 ;
  uint32_t pos2  = pos4  + _mem4ByteVarsUsed  * 4 ;
  uint32_t pos1  = pos2  + _mem2ByteVarsUsed  * 2 ;

  uint32_t stackPos = pos1 + _mem1ByteVarsUsed;

  uint32_t gapAlignment = stackAlignment;
  uint32_t gapSize = 0;

  // TODO: Not used!
  if (gapAlignment)
    Utils::alignDiff(stackPos, gapAlignment);
  stackPos += gapSize;

  uint32_t gapPos = stackPos;
  uint32_t allTotal = stackPos;

  // Vars - Allocated according to alignment/width.
  while (varCell != nullptr) {
    uint32_t size = varCell->getSize();
    uint32_t offset = 0;

    switch (size) {
      case  1: offset = pos1 ; pos1  += 1 ; break;
      case  2: offset = pos2 ; pos2  += 2 ; break;
      case  4: offset = pos4 ; pos4  += 4 ; break;
      case  8: offset = pos8 ; pos8  += 8 ; break;
      case 16: offset = pos16; pos16 += 16; break;
      case 32: offset = pos32; pos32 += 32; break;
      case 64: offset = pos64; pos64 += 64; break;

      default:
        ASMJIT_NOT_REACHED();
    }

    varCell->setOffset(static_cast<int32_t>(offset));
    varCell = varCell->_next;
  }

  // Stack - Allocated according to alignment/width.
  while (stackCell != nullptr) {
    uint32_t size = stackCell->getSize();
    uint32_t alignment = stackCell->getAlignment();
    uint32_t offset;

    // Try to fill the gap between variables/stack first.
    if (size <= gapSize && alignment <= gapAlignment) {
      offset = gapPos;

      gapSize -= size;
      gapPos -= size;

      if (alignment < gapAlignment)
        gapAlignment = alignment;
    }
    else {
      offset = stackPos;

      stackPos += size;
      allTotal += size;
    }

    stackCell->setOffset(offset);
    stackCell = stackCell->_next;
  }

  _memAllTotal = allTotal;
  return kErrorOk;
}