Esempio n. 1
0
int 
varcmp_offsets(const void *i1, const void *i2)
{
  if (offsets.off(*((Ident *) i1)) < offsets.off(*((Ident *) i2)))
    return -1;
  else if (offsets.off(*((Ident *) i1)) > offsets.off(*((Ident *) i2)))
    return 1;
  else
    return 0;
}
Esempio n. 2
0
void 
st_dfa_replace_indices(DFA *a, IdentList *newvars, IdentList *oldvars,
		       bool offnew, bool offold)
{
  if (newvars && oldvars && newvars != oldvars) {
    invariant(newvars->size() == oldvars->size());
  
    int *indexmap = new int[offsets.maxOffset()];
    
    IdentList::iterator i, j;
    bool dif = false;

    for(i = newvars->begin(), j = oldvars->begin();
	j != oldvars->end(); i++, j++) {
      int theold = offold ? offsets.off(*j) : *j;
      int thenew = offnew ? offsets.off(*i) : *i;
      indexmap[theold] = thenew;
      if (theold != thenew)
	dif = true;
    }

    if (dif) {
      Timer temp;

      if (options.time) {
	timer_replace_indices.start();
	if (options.statistics)
	  temp.start();
      }

      if (options.statistics)
	cout << "Replacing indices\n";

      dfaReplaceIndices(a, indexmap);
      num_replaces++;

      if (options.time) {
	timer_replace_indices.stop();
	if (options.statistics) {
	  temp.stop();
	  cout << "  Time: ";
	  temp.print();
	}
      }
    }    

    delete[] indexmap;

    if (options.intermediate)
      dfaPrintVerbose(a);
  }

  /*#warning  update_largest(a);*/
}
Esempio n. 3
0
Offsets DenseVectorN::getNonZeroOffsets() const
{
    Offsets offsetList;
    for (int i = 0, sz = x.size(); i < sz; ++i)
    {
        if (x[i] != 0.0)
        {
            offsetList.push_back(Offset(i, x[i]));
        }
    }
    return offsetList;
}
Esempio n. 4
0
void
st_gta_replace_indices(GTA *g, IdentList *newvars, IdentList *oldvars,
		       bool offnew, bool offold)
{
  if (newvars && oldvars && newvars != oldvars) {
    invariant(newvars->size() == oldvars->size());
  
    unsigned *indexmap = new unsigned[offsets.maxOffset()];
    
    IdentList::iterator i, j;
    bool dif = false;

    for(i = newvars->begin(), j = oldvars->begin();
        j != oldvars->end(); i++, j++) {
      int theold = offold ? offsets.off(*j) : *j;
      int thenew = offnew ? offsets.off(*i) : *i;
      indexmap[theold] = thenew;
      if (theold != thenew)
	dif = true;
    }

    if (dif) {
      Timer temp;

      if (options.time) {
	timer_replace_indices.start();
	if (options.statistics)
	  temp.start();
      }

      if (options.statistics) 
        cout << "Replacing indices\n";

      gtaReplaceIndices(g, indexmap);
      num_replaces++;

      if (options.time) {
	timer_replace_indices.stop();
	if (options.statistics) {
	  temp.stop();
	  cout << "  Time: ";
	  temp.print();
	}
      }
    }    

    delete[] indexmap;
  }

  update_largest(g);
}
Esempio n. 5
0
ColumnPtr ColumnArray::replicateNumber(const Offsets & replicate_offsets) const
{
    size_t col_size = size();
    if (col_size != replicate_offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    MutableColumnPtr res = cloneEmpty();

    if (0 == col_size)
        return res;

    ColumnArray & res_ = typeid_cast<ColumnArray &>(*res);

    const typename ColumnVector<T>::Container & src_data = typeid_cast<const ColumnVector<T> &>(*data).getData();
    const Offsets & src_offsets = getOffsets();

    typename ColumnVector<T>::Container & res_data = typeid_cast<ColumnVector<T> &>(res_.getData()).getData();
    Offsets & res_offsets = res_.getOffsets();

    res_data.reserve(data->size() / col_size * replicate_offsets.back());
    res_offsets.reserve(replicate_offsets.back());

    Offset prev_replicate_offset = 0;
    Offset prev_data_offset = 0;
    Offset current_new_offset = 0;

    for (size_t i = 0; i < col_size; ++i)
    {
        size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
        size_t value_size = src_offsets[i] - prev_data_offset;

        for (size_t j = 0; j < size_to_replicate; ++j)
        {
            current_new_offset += value_size;
            res_offsets.push_back(current_new_offset);

            if (value_size)
            {
                res_data.resize(res_data.size() + value_size);
                memcpy(&res_data[res_data.size() - value_size], &src_data[prev_data_offset], value_size * sizeof(T));
            }
        }

        prev_replicate_offset = replicate_offsets[i];
        prev_data_offset = src_offsets[i];
    }

    return res;
}
Esempio n. 6
0
void
Signature::make(IdentList &idents)
{
  size = idents.size();
  int *tab1 = new int[size];
  int *tab2 = new int[size];
  IdentList::iterator i;
  unsigned int x,y,s;
  
  for (i = idents.begin(), x = 0; 
       i != idents.end(); i++, x++)
    tab1[x] = tab2[x] = offsets.off(*i);
  
  qsort((int *) tab2, size, sizeof(int), sortcmp);
  
  sign = new int[size];
  hashvalue = 0;

  for (x = 0; x < size; x++) {
    for (y = 0, s = 0; tab2[y] != tab1[x]; y++)
      if (y < size && tab2[y] != tab2[y+1])
	s++;
    sign[x] = s;
    hashvalue = hashvalue*x+sign[x];
  }

  delete[] tab1;
  delete[] tab2;
}
Esempio n. 7
0
// returns rebased addresses
Offsets HexSearcher::FindOffsets(std::vector<unsigned char> const& pattern, size_t limit)
{
    Offsets offsets;
    ADDRESS begin = GetModuleBegin();
    ADDRESS end = GetModuleEnd();

    // loop through every hex value in the binary
    for (ADDRESS i = begin; (i + pattern.size()) < end; ++i)
    {
        if (limit && offsets.size() >= limit)
            break;

        size_t matches = 0;

        for (size_t j = 0; j < pattern.size(); j++)
        {
             // 0x00, any val
            if (pattern[j] == 0)
            {
                matches++;
                continue;
            }

            //ADDRESS static_address = STATIC_REBASE(i + j);

            // pattern doesn't match, retry @ next hex val
            unsigned char ch = *(unsigned char*)(i + j);
            if (ch != pattern[j])
                break;

            matches++;
        }

        if (matches == pattern.size())
        {
            offsets.insert(i);
            i += matches;
        }
    }

    return offsets;
}
Esempio n. 8
0
ColumnPtr ColumnFixedString::replicate(const Offsets & offsets) const
{
    size_t col_size = size();
    if (col_size != offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    auto res = ColumnFixedString::create(n);

    if (0 == col_size)
        return std::move(res);

    Chars_t & res_chars = res->chars;
    res_chars.resize(n * offsets.back());

    Offset curr_offset = 0;
    for (size_t i = 0; i < col_size; ++i)
        for (size_t next_offset = offsets[i]; curr_offset < next_offset; ++curr_offset)
            memcpySmallAllowReadWriteOverflow15(&res->chars[curr_offset * n], &chars[i * n], n);

    return std::move(res);
}
Esempio n. 9
0
DFA*
st_dfa_allpos(DFA *dfa, Ident i)
{
  DFA *t1, *t2;

  t1 = st_dfa_minimization(st_dfa_product(dfa, 
					  dfaAllPos(offsets.off(i)),
					  dfaAND,
					  dummyPos));
  t2 = st_dfa_minimization(st_dfa_project(t1, 
					  i,
					  dummyPos, false));
  /*#warning  update_largest(t2);*/
  return t2;
}
Esempio n. 10
0
ColumnPtr ColumnArray::replicateConst(const Offsets & replicate_offsets) const
{
    size_t col_size = size();
    if (col_size != replicate_offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    if (0 == col_size)
        return cloneEmpty();

    const Offsets & src_offsets = getOffsets();

    auto res_column_offsets = ColumnOffsets::create();
    Offsets & res_offsets = res_column_offsets->getData();
    res_offsets.reserve(replicate_offsets.back());

    Offset prev_replicate_offset = 0;
    Offset prev_data_offset = 0;
    Offset current_new_offset = 0;

    for (size_t i = 0; i < col_size; ++i)
    {
        size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
        size_t value_size = src_offsets[i] - prev_data_offset;

        for (size_t j = 0; j < size_to_replicate; ++j)
        {
            current_new_offset += value_size;
            res_offsets.push_back(current_new_offset);
        }

        prev_replicate_offset = replicate_offsets[i];
        prev_data_offset = src_offsets[i];
    }

    return ColumnArray::create(getData().cloneResized(current_new_offset), std::move(res_column_offsets));
}
Esempio n. 11
0
MatrixOpDataRcPtr MatrixOpData::inverse() const
{
    // Get the inverse matrix.
    MatrixArrayPtr invMatrixArray = m_array.inverse();
    // MatrixArray::inverse() will throw for singular matrices.

    // Calculate the inverse offset.
    const Offsets& offsets = getOffsets();
    Offsets invOffsets;
    if (offsets.isNotNull())
    {
        invMatrixArray->inner(offsets, invOffsets);
        invOffsets.scale(-1);
    }

    MatrixOpDataRcPtr invOp = std::make_shared<MatrixOpData>(getOutputBitDepth(), getInputBitDepth());
    invOp->setRGBA(&(invMatrixArray->getValues()[0]));
    invOp->setOffsets(invOffsets);

    // No need to call validate(), the invOp will have proper dimension,
    // bit-depths, matrix and offets values.

    return invOp;
}
Esempio n. 12
0
GTA *
st_gta_allpos(GTA *gta, Ident i)
{
  GTA *t1, *t2;
  IdentList *u = symbolTable.allRealUnivs();
  SSSet set = stateSpaces(u);
  delete u;
  t1 = st_gta_minimization(st_gta_product(gta,
					  gtaAllPos(offsets.off(i), set),
					  gtaAND,
					  dummyPos));
  t2 = st_gta_minimization(st_gta_project(t1,
					  i,
					  dummyPos, false));
  update_largest(t2);
  return t2;
}
Esempio n. 13
0
GTA * 
st_gta_project(GTA *g, Ident i, Pos &p, bool quotient) 
{
  Timer temp;

  if (options.time) {
    timer_project.start();
    if (options.statistics)
      temp.start();
  }
  
  if (options.statistics) {
    cout << "Right-quotient\n" << "Projecting #" << i;
    p.printsource();
    cout << "\n  ";
    print_stat(g);
    cout << " -> ";
    cout.flush();
  }
  
  codeTable->begin();
  GTA *result = gtaQuotientAndProject(g, offsets.off(i), quotient);
  codeTable->done();
  
  num_projections++;
  num_right_quotients++;

  if (options.statistics) {
    print_stat(result);
    cout << "\n";
  }
  
  if (options.time) {
    timer_project.stop();
    if (options.statistics) {
      temp.stop();
      cout << "  Time: ";
      temp.print();
    }
  }

  gtaFree(g);

  update_largest(result);
  return result;
}
Esempio n. 14
0
ColumnPtr ColumnArray::replicate(const Offsets & replicate_offsets) const
{
    if (replicate_offsets.empty())
        return cloneEmpty();

    if (typeid_cast<const ColumnUInt8 *>(data.get()))    return replicateNumber<UInt8>(replicate_offsets);
    if (typeid_cast<const ColumnUInt16 *>(data.get()))   return replicateNumber<UInt16>(replicate_offsets);
    if (typeid_cast<const ColumnUInt32 *>(data.get()))   return replicateNumber<UInt32>(replicate_offsets);
    if (typeid_cast<const ColumnUInt64 *>(data.get()))   return replicateNumber<UInt64>(replicate_offsets);
    if (typeid_cast<const ColumnInt8 *>(data.get()))     return replicateNumber<Int8>(replicate_offsets);
    if (typeid_cast<const ColumnInt16 *>(data.get()))    return replicateNumber<Int16>(replicate_offsets);
    if (typeid_cast<const ColumnInt32 *>(data.get()))    return replicateNumber<Int32>(replicate_offsets);
    if (typeid_cast<const ColumnInt64 *>(data.get()))    return replicateNumber<Int64>(replicate_offsets);
    if (typeid_cast<const ColumnFloat32 *>(data.get()))  return replicateNumber<Float32>(replicate_offsets);
    if (typeid_cast<const ColumnFloat64 *>(data.get()))  return replicateNumber<Float64>(replicate_offsets);
    if (typeid_cast<const ColumnString *>(data.get()))   return replicateString(replicate_offsets);
    if (typeid_cast<const ColumnConst *>(data.get()))    return replicateConst(replicate_offsets);
    if (typeid_cast<const ColumnNullable *>(data.get())) return replicateNullable(replicate_offsets);
    if (typeid_cast<const ColumnTuple *>(data.get()))    return replicateTuple(replicate_offsets);
    return replicateGeneric(replicate_offsets);
}
Esempio n. 15
0
ColumnPtr ColumnArray::replicateGeneric(const Offsets & replicate_offsets) const
{
    size_t col_size = size();
    if (col_size != replicate_offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    MutableColumnPtr res = cloneEmpty();
    ColumnArray & res_concrete = static_cast<ColumnArray &>(*res);

    if (0 == col_size)
        return res;

    IColumn::Offset prev_offset = 0;
    for (size_t i = 0; i < col_size; ++i)
    {
        size_t size_to_replicate = replicate_offsets[i] - prev_offset;
        prev_offset = replicate_offsets[i];

        for (size_t j = 0; j < size_to_replicate; ++j)
            res_concrete.insertFrom(*this, i);
    }

    return res;
}
Esempio n. 16
0
void Layer::drawPixmap()
{
    if ((boundingRect().width() == 0) || (boundingRect().height() == 0))
        return;

    // TODO Forward
    if (m_currentPixmap)
        delete m_currentPixmap;

    m_currentPixmap = new QPixmap(boundingRect().width() * m_areaToDraw, boundingRect().height());

    QPainter p(m_currentPixmap);
        int xPoint = 0;
        for (int i = 0; i < m_offsets[m_columnOffset].size(); i++) {
            Offsets offset = m_offsets[m_columnOffset].at(i);

            if (((m_type == Quasi::MirroredType) && (i != 0)
                    && (offset.point() - m_latestPoint < 0))
                    || m_shouldMirror) {
                m_drawingMirrored = !m_drawingMirrored;
                m_shouldMirror = false;
            }

            QPixmap pix = generatePartialPixmap(offset.point(), offset.size());
            p.drawPixmap(xPoint, 0, pix);

            xPoint += pix.width();
            m_latestPoint = offset.point();

            if ((m_type == Quasi::MirroredType)
                    && (i == m_offsets[m_columnOffset].size() - 1)
                    && (offset.size() < m_numColumns))
                m_shouldMirror = true;
        }

        if (m_direction == Quasi::ForwardDirection)
            m_columnOffset = (m_columnOffset - 1 < 0) ? m_offsets.size() - 1 : m_columnOffset - 1;
        else
            m_columnOffset = (m_columnOffset + 1) % m_offsets.size();
    p.end();
}
Esempio n. 17
0
ColumnPtr ColumnArray::replicateString(const Offsets & replicate_offsets) const
{
    size_t col_size = size();
    if (col_size != replicate_offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    MutableColumnPtr res = cloneEmpty();

    if (0 == col_size)
        return res;

    ColumnArray & res_ = static_cast<ColumnArray &>(*res);

    const ColumnString & src_string = typeid_cast<const ColumnString &>(*data);
    const ColumnString::Chars & src_chars = src_string.getChars();
    const Offsets & src_string_offsets = src_string.getOffsets();
    const Offsets & src_offsets = getOffsets();

    ColumnString::Chars & res_chars = typeid_cast<ColumnString &>(res_.getData()).getChars();
    Offsets & res_string_offsets = typeid_cast<ColumnString &>(res_.getData()).getOffsets();
    Offsets & res_offsets = res_.getOffsets();

    res_chars.reserve(src_chars.size() / col_size * replicate_offsets.back());
    res_string_offsets.reserve(src_string_offsets.size() / col_size * replicate_offsets.back());
    res_offsets.reserve(replicate_offsets.back());

    Offset prev_replicate_offset = 0;

    Offset prev_src_offset = 0;
    Offset prev_src_string_offset = 0;

    Offset current_res_offset = 0;
    Offset current_res_string_offset = 0;

    for (size_t i = 0; i < col_size; ++i)
    {
        /// How much to replicate the array.
        size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
        /// The number of rows in the array.
        size_t value_size = src_offsets[i] - prev_src_offset;
        /// Number of characters in rows of the array, including zero/null bytes.
        size_t sum_chars_size = value_size == 0 ? 0 : (src_string_offsets[prev_src_offset + value_size - 1] - prev_src_string_offset);

        for (size_t j = 0; j < size_to_replicate; ++j)
        {
            current_res_offset += value_size;
            res_offsets.push_back(current_res_offset);

            size_t prev_src_string_offset_local = prev_src_string_offset;
            for (size_t k = 0; k < value_size; ++k)
            {
                /// Size of one row.
                size_t chars_size = src_string_offsets[k + prev_src_offset] - prev_src_string_offset_local;

                current_res_string_offset += chars_size;
                res_string_offsets.push_back(current_res_string_offset);

                prev_src_string_offset_local += chars_size;
            }

            if (sum_chars_size)
            {
                /// Copies the characters of the array of rows.
                res_chars.resize(res_chars.size() + sum_chars_size);
                memcpySmallAllowReadWriteOverflow15(
                    &res_chars[res_chars.size() - sum_chars_size], &src_chars[prev_src_string_offset], sum_chars_size);
            }
        }

        prev_replicate_offset = replicate_offsets[i];
        prev_src_offset = src_offsets[i];
        prev_src_string_offset += sum_chars_size;
    }

    return res;
}
Esempio n. 18
0
bool
ModuleGenerator::finishCodegen(StaticLinkData* link)
{
    uint32_t offsetInWhole = masm_.size();

    // Generate stubs in a separate MacroAssembler since, otherwise, for modules
    // larger than the JumpImmediateRange, even local uses of Label will fail
    // due to the large absolute offsets temporarily stored by Label::bind().

    Vector<Offsets> entries(cx_);
    Vector<ProfilingOffsets> interpExits(cx_);
    Vector<ProfilingOffsets> jitExits(cx_);
    EnumeratedArray<JumpTarget, JumpTarget::Limit, Offsets> jumpTargets;
    ProfilingOffsets badIndirectCallExit;
    Offsets interruptExit;

    {
        TempAllocator alloc(&lifo_);
        MacroAssembler masm(MacroAssembler::AsmJSToken(), alloc);

        if (!entries.resize(numExports()))
            return false;
        for (uint32_t i = 0; i < numExports(); i++) {
            uint32_t target = exportMap_->exportFuncIndices[i];
            const Sig& sig = module_->exports[i].sig();
            entries[i] = GenerateEntry(masm, target, sig, usesHeap());
        }

        if (!interpExits.resize(numImports()))
            return false;
        if (!jitExits.resize(numImports()))
            return false;
        for (uint32_t i = 0; i < numImports(); i++) {
            interpExits[i] = GenerateInterpExit(masm, module_->imports[i], i);
            jitExits[i] = GenerateJitExit(masm, module_->imports[i], usesHeap());
        }

        for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit))
            jumpTargets[target] = GenerateJumpTarget(masm, target);

        badIndirectCallExit = GenerateBadIndirectCallExit(masm);
        interruptExit = GenerateInterruptStub(masm);

        if (masm.oom() || !masm_.asmMergeWith(masm))
            return false;
    }

    // Adjust each of the resulting Offsets (to account for being merged into
    // masm_) and then create code ranges for all the stubs.

    for (uint32_t i = 0; i < numExports(); i++) {
        entries[i].offsetBy(offsetInWhole);
        module_->exports[i].initStubOffset(entries[i].begin);
        if (!module_->codeRanges.emplaceBack(CodeRange::Entry, entries[i]))
            return false;
    }

    for (uint32_t i = 0; i < numImports(); i++) {
        interpExits[i].offsetBy(offsetInWhole);
        module_->imports[i].initInterpExitOffset(interpExits[i].begin);
        if (!module_->codeRanges.emplaceBack(CodeRange::ImportInterpExit, interpExits[i]))
            return false;

        jitExits[i].offsetBy(offsetInWhole);
        module_->imports[i].initJitExitOffset(jitExits[i].begin);
        if (!module_->codeRanges.emplaceBack(CodeRange::ImportJitExit, jitExits[i]))
            return false;
    }

    for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit)) {
        jumpTargets[target].offsetBy(offsetInWhole);
        if (!module_->codeRanges.emplaceBack(CodeRange::Inline, jumpTargets[target]))
            return false;
    }

    badIndirectCallExit.offsetBy(offsetInWhole);
    if (!module_->codeRanges.emplaceBack(CodeRange::ErrorExit, badIndirectCallExit))
        return false;

    interruptExit.offsetBy(offsetInWhole);
    if (!module_->codeRanges.emplaceBack(CodeRange::Inline, interruptExit))
        return false;

    // Fill in StaticLinkData with the offsets of these stubs.

    link->pod.outOfBoundsOffset = jumpTargets[JumpTarget::OutOfBounds].begin;
    link->pod.interruptOffset = interruptExit.begin;

    for (uint32_t sigIndex = 0; sigIndex < numSigs_; sigIndex++) {
        const TableModuleGeneratorData& table = shared_->sigToTable[sigIndex];
        if (table.elemFuncIndices.empty())
            continue;

        Uint32Vector elemOffsets;
        if (!elemOffsets.resize(table.elemFuncIndices.length()))
            return false;

        for (size_t i = 0; i < table.elemFuncIndices.length(); i++) {
            uint32_t funcIndex = table.elemFuncIndices[i];
            if (funcIndex == BadIndirectCall)
                elemOffsets[i] = badIndirectCallExit.begin;
            else
                elemOffsets[i] = funcEntry(funcIndex);
        }

        if (!link->funcPtrTables.emplaceBack(table.globalDataOffset, Move(elemOffsets)))
            return false;
    }

    // Only call convertOutOfRangeBranchesToThunks after all other codegen that may
    // emit new jumps to JumpTargets has finished.

    if (!convertOutOfRangeBranchesToThunks())
        return false;

    // Now that all thunks have been generated, patch all the thunks.

    for (CallThunk& callThunk : module_->callThunks) {
        uint32_t funcIndex = callThunk.u.funcIndex;
        callThunk.u.codeRangeIndex = funcIndexToCodeRange_[funcIndex];
        masm_.patchThunk(callThunk.offset, funcEntry(funcIndex));
    }

    for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit)) {
        for (uint32_t thunkOffset : jumpThunks_[target])
            masm_.patchThunk(thunkOffset, jumpTargets[target].begin);
    }

    // Code-generation is complete!

    masm_.finish();
    return !masm_.oom();
}
Esempio n. 19
0
bool
ModuleGenerator::finishCodegen()
{
    uint32_t offsetInWhole = masm_.size();

    uint32_t numFuncExports = metadata_->funcExports.length();
    MOZ_ASSERT(numFuncExports == exportedFuncs_.count());

    // Generate stubs in a separate MacroAssembler since, otherwise, for modules
    // larger than the JumpImmediateRange, even local uses of Label will fail
    // due to the large absolute offsets temporarily stored by Label::bind().

    OffsetVector entries;
    ProfilingOffsetVector interpExits;
    ProfilingOffsetVector jitExits;
    EnumeratedArray<JumpTarget, JumpTarget::Limit, Offsets> jumpTargets;
    Offsets interruptExit;

    {
        TempAllocator alloc(&lifo_);
        MacroAssembler masm(MacroAssembler::AsmJSToken(), alloc);

        if (!entries.resize(numFuncExports))
            return false;
        for (uint32_t i = 0; i < numFuncExports; i++)
            entries[i] = GenerateEntry(masm, metadata_->funcExports[i]);

        if (!interpExits.resize(numFuncImports()))
            return false;
        if (!jitExits.resize(numFuncImports()))
            return false;
        for (uint32_t i = 0; i < numFuncImports(); i++) {
            interpExits[i] = GenerateInterpExit(masm, metadata_->funcImports[i], i);
            jitExits[i] = GenerateJitExit(masm, metadata_->funcImports[i]);
        }

        for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit))
            jumpTargets[target] = GenerateJumpTarget(masm, target);

        interruptExit = GenerateInterruptStub(masm);

        if (masm.oom() || !masm_.asmMergeWith(masm))
            return false;
    }

    // Adjust each of the resulting Offsets (to account for being merged into
    // masm_) and then create code ranges for all the stubs.

    for (uint32_t i = 0; i < numFuncExports; i++) {
        entries[i].offsetBy(offsetInWhole);
        metadata_->funcExports[i].initEntryOffset(entries[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::Entry, entries[i]))
            return false;
    }

    for (uint32_t i = 0; i < numFuncImports(); i++) {
        interpExits[i].offsetBy(offsetInWhole);
        metadata_->funcImports[i].initInterpExitOffset(interpExits[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::ImportInterpExit, interpExits[i]))
            return false;

        jitExits[i].offsetBy(offsetInWhole);
        metadata_->funcImports[i].initJitExitOffset(jitExits[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::ImportJitExit, jitExits[i]))
            return false;
    }

    for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit)) {
        jumpTargets[target].offsetBy(offsetInWhole);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, jumpTargets[target]))
            return false;
    }

    interruptExit.offsetBy(offsetInWhole);
    if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, interruptExit))
        return false;

    // Fill in LinkData with the offsets of these stubs.

    linkData_.interruptOffset = interruptExit.begin;
    linkData_.outOfBoundsOffset = jumpTargets[JumpTarget::OutOfBounds].begin;
    linkData_.unalignedAccessOffset = jumpTargets[JumpTarget::UnalignedAccess].begin;
    linkData_.badIndirectCallOffset = jumpTargets[JumpTarget::BadIndirectCall].begin;

    // Only call convertOutOfRangeBranchesToThunks after all other codegen that may
    // emit new jumps to JumpTargets has finished.

    if (!convertOutOfRangeBranchesToThunks())
        return false;

    // Now that all thunks have been generated, patch all the thunks.

    for (CallThunk& callThunk : metadata_->callThunks) {
        uint32_t funcIndex = callThunk.u.funcIndex;
        callThunk.u.codeRangeIndex = funcIndexToCodeRange_[funcIndex];
        masm_.patchThunk(callThunk.offset, funcCodeRange(funcIndex).funcNonProfilingEntry());
    }

    for (JumpTarget target : MakeEnumeratedRange(JumpTarget::Limit)) {
        for (uint32_t thunkOffset : jumpThunks_[target])
            masm_.patchThunk(thunkOffset, jumpTargets[target].begin);
    }

    // Code-generation is complete!

    masm_.finish();
    return !masm_.oom();
}
Esempio n. 20
0
DFA* 
st_dfa_project(DFA *a, Ident i, Pos &p, bool quotient) 
{
  Timer temp1, temp2;

  int a_ns = a->ns;
  
  if (options.time) {
    timer_right_quotient.start();
    if (options.statistics)
      temp1.start();
  }

  if (options.statistics)
    cout << "Right-quotient\n";

  if (quotient) {
    codeTable->begin();
    dfaRightQuotient(a, offsets.off(i));
    codeTable->done();
    num_right_quotients++;
  }

  if (options.time) {
    timer_right_quotient.stop();
    if (options.statistics) {
      temp1.stop();
      cout << "  Time: ";
      temp1.print();
    }
  }
 
  if (options.time) {
    timer_project.start();
    if (options.statistics)
      temp2.start();
  }

  if (options.statistics) {
    cout << "Projecting #" << i;
    p.printsource();
    cout << "\n  (" << a_ns << "," << bdd_size(a->bddm) << ") -> ";
    cout.flush();
  }

  codeTable->begin();
  DFA *result = dfaProject(a, offsets.off(i));
  codeTable->done();
  num_projections++;

  if (options.statistics)
    cout << "("  << result->ns << "," << bdd_size(result->bddm) << ")\n";

  if (options.time) {
    timer_project.stop();
    if (options.statistics) {
      temp2.stop();
      cout << "  Time: ";
      temp2.print();
    }
  }

  dfaFree(a);

  /*#warning  update_largest(result);*/
  return result;
}
Esempio n. 21
0
int 
main(int argc, char *argv[])
{
  std::set_new_handler(&mem_error);

  if (!ParseArguments(argc, argv)) {
    Usage();
    exit(-1);
  }

  // Disable core dump
  struct rlimit r_core;
  r_core.rlim_cur = 0;
  r_core.rlim_max = 0;
  setrlimit(RLIMIT_CORE, &r_core);

  // Set demo limits 
  if (options.demo) {
    struct rlimit r_cpu, r_as;
    memlimit = true;

    r_cpu.rlim_cur = 30; // max 30 secs.
    r_cpu.rlim_max = 30;
    setrlimit(RLIMIT_CPU, &r_cpu);

    r_as.rlim_cur = 20971520; // max 20MB
    r_as.rlim_max = 20971520;
    setrlimit(RLIMIT_DATA, &r_as);

    signal(SIGXCPU, &cpuLimit);
  }

  initTimer();
  Timer timer_total;
  timer_total.start();
  
  ///////// PARSING ////////////////////////////////////////////////////////

  if (options.printProgress)
    cout << "MONA v" << VERSION << "-" << RELEASE <<  " for WS1S/WS2S\n"
      "Copyright (C) 1997-2008 BRICS\n\n"
      "PARSING\n";

  Timer timer_parsing;
  timer_parsing.start();

  loadFile(inputFileName);
  yyparse();
  MonaAST *ast = untypedAST->typeCheck();
  lastPosVar = ast->lastPosVar;
  allPosVar = ast->allPosVar;

  timer_parsing.stop();

  if (options.printProgress) {
    cout << "Time: ";
    timer_parsing.print();
  }

  delete untypedAST;

  if (options.dump) {
    // Dump AST for main formula, verify formulas, and assertion
    cout << "Main formula:\n";
    (ast->formula)->dump();
    Deque<ASTForm *>::iterator vf;
    Deque<char *>::iterator vt;
    for (vf = ast->verifyformlist.begin(), vt = ast->verifytitlelist.begin();
	 vf != ast->verifyformlist.end(); vf++, vt++) {
      cout << "\n\nFormula " << *vt << ":\n";
      (*vf)->dump();
    }
    cout << "\n\nAssertions:\n";
    (ast->assertion)->dump();
    cout << "\n";

    if (lastPosVar != -1)
      cout << "\nLastPos variable: " 
	   << symbolTable.lookupSymbol(lastPosVar) << "\n";
    if (allPosVar != -1)
      cout << "\nAllPos variable: " 
	   << symbolTable.lookupSymbol(allPosVar) << "\n";
    
    // Dump ASTs for predicates and macros
    PredLibEntry *pred = predicateLib.first();
    while (pred != NULL) {
      if (pred->isMacro)
	cout << "\nMacro '";
      else
	cout << "\nPredicate '";
      cout << symbolTable.lookupSymbol(pred->name) 
	   << "':\n";
      (pred->ast)->dump();
      cout << "\n";
      pred = predicateLib.next();
    }

    // Dump restrictions
    if (symbolTable.defaultRestriction1) {
      cout << "\nDefault first-order restriction (" 
	   << symbolTable.lookupSymbol(symbolTable.defaultIdent1) << "):\n";
      symbolTable.defaultRestriction1->dump();
      cout << "\n";
    }
    if (symbolTable.defaultRestriction2) {
      cout << "\nDefault second-order restriction (" 
	   << symbolTable.lookupSymbol(symbolTable.defaultIdent2) << "):\n";
      symbolTable.defaultRestriction2->dump();
      cout << "\n";
    }

    Ident id;
    for (id = 0; id < (Ident) symbolTable.noIdents; id++) {
      Ident t;
      ASTForm *f = symbolTable.getRestriction(id, &t);
      if (f) {
	cout << "\nRestriction for #" << id << " (" 
	     << symbolTable.lookupSymbol(id) << "):";
	if (t != -1)
	  cout << " default\n";
	else {
	  cout << "\n";
	  f->dump();
	  cout << "\n";
	}
      }
    }
  }

  if (options.mode != TREE && 
      (options.graphvizSatisfyingEx || options.graphvizCounterEx ||
       options.inheritedAcceptance)) 
    cout << "Warning: options -gc, -gs, and -h are only used in tree mode\n";
  if (options.mode == TREE && options.graphvizDFA)
    cout << "Warning: option -gw is only used in linear mode\n";
  
  if (options.mode == TREE && (options.dump || options.whole) && 
      !options.externalWhole)
    printGuide();


  ///////// CODE GENERATION ////////////////////////////////////////////////
  
  if (options.printProgress)
    cout << "\nCODE GENERATION\n";
  Timer timer_gencode;
  timer_gencode.start();
  
  // Generate code
  codeTable = new CodeTable;
  VarCode formulaCode = ast->formula->makeCode();
  VarCode assertionCode = ast->assertion->makeCode();
  Deque<VarCode> verifyCode;
  /* #warning NEW: 'VERIFY' */
  for (Deque<ASTForm *>::iterator i = ast->verifyformlist.begin(); 
       i != ast->verifyformlist.end(); i++)
    verifyCode.push_back((*i)->makeCode());

  // Implicitly assert restrictions for all global variables
  for (IdentList::iterator i = ast->globals.begin(); 
       i != ast->globals.end(); i++)
    assertionCode = andList(assertionCode, getRestriction(*i, NULL));

  // Restrict assertion if not trivial
  if (assertionCode.code->kind != cTrue)
    assertionCode = codeTable->insert
      (new Code_Restrict(assertionCode, assertionCode.code->pos));

  // Add assertion to main formula and to all verify formulas
  for (Deque<VarCode>::iterator i = verifyCode.begin(); 
       i != verifyCode.end(); i++) {
    assertionCode.code->refs++;
    *i = andList(*i, VarCode(copy(assertionCode.vars), assertionCode.code));
  }
  formulaCode = andList(formulaCode, assertionCode);

  timer_gencode.stop();
  if (options.printProgress) {
    codeTable->print_statistics();
    /* if (options.dump && options.statistics)
      codeTable->print_sizes(); */
    cout << "Time: ";
    timer_gencode.print();
  }
  
  ///////// REORDER BDD OFFSETS ////////////////////////////////////////////

  if (options.reorder >= 1) {
    Timer timer_reorder;
    timer_reorder.start();
    if (options.printProgress)
      cout << "\nREORDERING\n";

    // reorder using heuristics
    offsets.reorder();
    
    // regenerate DAG in new codetable
    CodeTable *oldCodeTable = codeTable, *newCodeTable = new CodeTable;
    IdentList emptylist;
    codeTable = newCodeTable;
    regenerate = true; // force making new nodes
    VarCode newcode = formulaCode.substCopy(&emptylist, &emptylist);
    Deque<VarCode> newverifycode;
    for (Deque<VarCode>::iterator i = verifyCode.begin(); 
	 i != verifyCode.end(); i++)
      newverifycode.push_back((*i).substCopy(&emptylist, &emptylist));
    codeTable->clearSCTable();
    regenerate = false;
    codeTable = oldCodeTable;
    formulaCode.remove();
    for (Deque<VarCode>::iterator i = verifyCode.begin(); 
	 i != verifyCode.end(); i++)
      (*i).remove();
    formulaCode = newcode;
    verifyCode.reset();
    for (Deque<VarCode>::iterator i = newverifycode.begin(); 
	 i != newverifycode.end(); i++)
      verifyCode.push_back(*i);
    delete oldCodeTable;
    codeTable = newCodeTable;

    if (options.printProgress) {
      codeTable->print_statistics2();
      cout << "Time: ";
      timer_reorder.print();
    }
  }

  ///////// REDUCTION AND CODE DUMPING /////////////////////////////////////

  if (options.optimize >= 1) {
    if (options.printProgress)
      cout << "\nREDUCTION\n";
    Timer timer_reduction;
    timer_reduction.start();
    
    // Reduce
    formulaCode.reduceAll(&verifyCode);

    timer_reduction.stop();
    if (options.printProgress) {
      codeTable->print_reduction_statistics();
      /* if (options.dump && options.statistics)
	 codeTable->print_sizes(); */
      cout << "Time: ";
      timer_reduction.print();
    }
  }
  
  if (options.dump) {
    // Dump symboltable
    symbolTable.dump();
    
    // Dump code
    cout << "\nMain formula:\n";
    formulaCode.dump();
    cout << "\n\n";
    Deque<VarCode>::iterator i;
    Deque<char *>::iterator j;
    for (i = verifyCode.begin(), j = ast->verifytitlelist.begin(); 
	 i != verifyCode.end(); i++, j++) {
      cout << "Formula " << *j << ":\n";
      (*i).dump();
      cout << "\n\n";
    }
  }
  
  if (options.graphvizDAG) {
    printf("digraph MONA_CODE_DAG {\n"
	   " size = \"7.5,10.5\";\n"
	   " main [shape = plaintext];\n"
	   " main -> L%lx;\n", 
	   (unsigned long) formulaCode.code);
    formulaCode.code->viz();
    Deque<VarCode>::iterator i;
    Deque<char *>::iterator j;
    for (i = verifyCode.begin(), j = ast->verifytitlelist.begin(); 
	 i != verifyCode.end(); i++, j++) {
      printf(" \"%s\" [shape = plaintext];\n"
	     " \"%s\" -> L%lx;\n", 
	     *j, *j, (unsigned long) (*i).code);
      (*i).code->viz();
    }
    formulaCode.unmark();
    for (Deque<VarCode>::iterator i = verifyCode.begin(); 
	 i != verifyCode.end(); i++)
      (*i).unmark();
    cout << "}\n";
  }

  ///////// AUTOMATON CONSTRUCTION /////////////////////////////////////////

  // Make variable lists
  Deque<char *> *verifytitlelist = ast->verifytitlelist.copy();
  if (lastPosVar != -1)
    ast->globals.remove(lastPosVar); 
  if (allPosVar != -1)
    ast->globals.remove(allPosVar); 
  ast->globals.sort(); // sort by id (= index)
  int numVars = ast->globals.size();
  int ix = 0;
  char **vnames = new char*[numVars];
  unsigned *offs = new unsigned[numVars];
  char *types = new char[numVars];
  int **univs = new int*[numVars];
  int *trees = new int[numVars];
  SSSet *statespaces = new SSSet[numVars];
  IdentList sign, freeVars;
  IdentList::iterator id;
  for (id = ast->globals.begin(); id != ast->globals.end(); id++, ix++) {
    statespaces[ix] = stateSpaces(*id);
    vnames[ix] = symbolTable.lookupSymbol(*id);
    offs[ix] = offsets.off(*id);
    sign.push_back(ix);
    freeVars.push_back(*id);
    switch (symbolTable.lookupType(*id)) {
    case VarnameTree:
      trees[ix] = 1;
      break;
    default:
      trees[ix] = 0;
    }
    IdentList *uu = symbolTable.lookupUnivs(*id);
    if (uu) {
      unsigned j;
      univs[ix] = new int[uu->size()+1];
      for (j = 0; j < uu->size(); j++)
	univs[ix][j] = symbolTable.lookupUnivNumber(uu->get(j));
      univs[ix][j] = -1;
    }
    else
      univs[ix] = 0;
    switch (symbolTable.lookupType(*id)) 
      {
      case Varname0: 
	types[ix] = 0;
	break;
      case Varname1: 
	types[ix] = 1;
	break;
      default:
	types[ix] = 2;
	break;
      }
  }
  
  if (options.printProgress)
    cout << "\nAUTOMATON CONSTRUCTION\n";

  Timer timer_automaton;
  timer_automaton.start();
  
  DFA *dfa = 0;
  Deque<DFA *> dfalist;
  GTA *gta = 0;
  Deque<GTA *> gtalist;
  
  // Initialize
  bdd_init();
  codeTable->init_print_progress();

  if (options.mode != TREE) { 
    // Generate DFAs
    dfa = formulaCode.DFATranslate();
    if (lastPosVar != -1)
      dfa = st_dfa_lastpos(dfa, lastPosVar);
    if (allPosVar != -1)
      dfa = st_dfa_allpos(dfa, allPosVar);
    for (Deque<VarCode>::iterator i = verifyCode.begin(); 
	 i != verifyCode.end(); i++) {
      DFA *d = (*i).DFATranslate();
      if (lastPosVar != -1)
	d = st_dfa_lastpos(d, lastPosVar);
      if (allPosVar != -1)
	d = st_dfa_allpos(d, allPosVar);
      dfalist.push_back(d);
    }
  }
  else { 
    // Generate GTAs
    gta = formulaCode.GTATranslate();
    if (allPosVar != -1)
      gta = st_gta_allpos(gta, allPosVar);
    for (Deque<VarCode>::iterator i = verifyCode.begin(); 
	 i != verifyCode.end(); i++) {
      GTA *g = (*i).GTATranslate();
      if (allPosVar != -1)
	g = st_gta_allpos(g, allPosVar);
      gtalist.push_back(g);
    }
  }
  formulaCode.remove();
  for (Deque<VarCode>::iterator i = verifyCode.begin(); 
       i != verifyCode.end(); i++)
    (*i).remove();
  
  timer_automaton.stop();
  if (options.printProgress) {
    if (options.statistics)
      cout << "Total automaton construction time: ";
    else
      cout << "Time: ";
    timer_automaton.print();
  }

  delete ast;
  delete codeTable;

  ///////// PRINT AUTOMATON ////////////////////////////////////////////////

  DFA *dfa2 = dfa;
  GTA *gta2 = gta;
  Deque<DFA *> *dfalist2 = &dfalist;
  Deque<GTA *> *gtalist2 = &gtalist;

  if (options.whole &&
      !options.externalWhole)
    cout << "\n";
  if (options.unrestrict) {
    // Unrestrict automata
    if (options.mode != TREE) {
      DFA *t = dfaCopy(dfa2);
      dfaUnrestrict(t);
      dfa2 = dfaMinimize(t);
      dfaFree(t);
      dfalist2 = new Deque<DFA *>;
      for (Deque<DFA *>::iterator i = dfalist.begin(); i != dfalist.end(); i++) {
	t = dfaCopy(*i);
	dfaUnrestrict(t);
	dfalist2->push_back(dfaMinimize(t));
	dfaFree(t);
      }
    }
    else {
      GTA *t = gtaCopy(gta2);
      gtaUnrestrict(t);
      gta2 = gtaMinimize(t);
      gtaFree(t);
      gtalist2 = new Deque<GTA *>;
      for (Deque<GTA *>::iterator i = gtalist.begin(); i != gtalist.end(); i++) {
	t = gtaCopy(*i);
	gtaUnrestrict(t);
	gtalist2->push_back(gtaMinimize(t));
	gtaFree(t);	
      }
    }
  }

  if (options.whole)
    // Print whole automaton
    if (options.mode != TREE) {
      if (options.externalWhole) {
	if (!dfalist.empty())
	  cout << "Main formula:\n";
	DFA *t = dfaCopy(dfa2);
	st_dfa_replace_indices(t, &sign, &freeVars, false, true);
	dfaExport(t, 0, numVars, vnames, types);
	dfaFree(t);
	Deque<DFA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = dfalist2->begin(), j = verifytitlelist->begin();
	     i != dfalist2->end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  t = dfaCopy(*i);
	  st_dfa_replace_indices(t, &sign, &freeVars, false, true);
	  dfaExport(t, 0, numVars, vnames, types);
	  dfaFree(t);
	}
      }
      else if (options.graphvizDFA) {
	dfaPrintGraphviz(dfa2, numVars, offs);
	for (Deque<DFA *>::iterator i = dfalist2->begin(); i != dfalist2->end(); i++)
	  dfaPrintGraphviz(*i, numVars, offs);
      }
      else {
	if (!dfalist.empty())
	  cout << "Main formula:\n";
	dfaPrint(dfa2, numVars, vnames, offs);
	Deque<DFA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = dfalist2->begin(), j = verifytitlelist->begin(); 
	     i != dfalist2->end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  dfaPrint(*i, numVars, vnames, offs);
	}
      }
    }
    else {
      if (options.externalWhole) {
	if (!gtalist.empty())
	  cout << "Main formula:\n";
	GTA *t = gtaCopy(gta2);
	st_gta_replace_indices(t, &sign, &freeVars, false, true);
	gtaExport(t, 0, numVars, vnames, types, statespaces, 
		  options.inheritedAcceptance);
	gtaFree(t);
	Deque<GTA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = gtalist2->begin(), j = verifytitlelist->begin();
	     i != gtalist2->end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  t = gtaCopy(*i);
	  st_gta_replace_indices(t, &sign, &freeVars, false, true);
	  gtaExport(t, 0, numVars, vnames, types, statespaces, 
		    options.inheritedAcceptance);
	  gtaFree(t);
	}
      }
      else {
	if (!gtalist.empty())
	  cout << "Main formula:\n";
	gtaPrint(gta2, offs, numVars, vnames, 
		 options.inheritedAcceptance);
	Deque<GTA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = gtalist2->begin(), j = verifytitlelist->begin();
	     i != gtalist2->end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  gtaPrint(*i, offs, numVars, vnames, 
		   options.inheritedAcceptance);
	}
      }
    }
  else if (options.analysis &&
	   !options.graphvizSatisfyingEx &&
	   !options.graphvizCounterEx &&
	   options.printProgress) {
    // Print summary only
    if (options.mode != TREE) {
      if (!dfalist.empty())
	cout << "Main formula:";
      dfaPrintVitals(dfa2);
      Deque<DFA *>::iterator i;
      Deque<char *>::iterator j;
      for (i = dfalist2->begin(), j = verifytitlelist->begin(); 
	   i != dfalist2->end(); i++, j++) {
	cout << "\nFormula " << *j << ":";
	dfaPrintVitals(*i);
      }
    }
    else {
      if (!gtalist.empty())
	cout << "Main formula:";
      gtaPrintTotalSize(gta2);
      Deque<GTA *>::iterator i;
      Deque<char *>::iterator j;
      for (i = gtalist2->begin(), j = verifytitlelist->begin(); 
	   i != gtalist2->end(); i++, j++) {
	cout << "\nFormula " << *j << ":";
	gtaPrintTotalSize(*i);
      }
    }
  }
  if (dfa2 != dfa) {
    dfaFree(dfa2);
    for (Deque<DFA *>::iterator i = dfalist2->begin(); i != dfalist2->end(); i++) 
      dfaFree(*i);
    delete dfalist2;
  }
  if (gta2 != gta) {
    gtaFree(gta2);
    for (Deque<GTA *>::iterator i = gtalist2->begin(); i != gtalist2->end(); i++) 
      gtaFree(*i);
    delete gtalist2;
  }

  ///////// AUTOMATON ANALYSIS /////////////////////////////////////////////

  if (options.analysis) {
    if (options.printProgress)
      cout << "\nANALYSIS\n";
    
    if (options.mode != TREE) {
      if (!dfalist.empty())
	cout << "Main formula:\n";
      dfaAnalyze(dfa, numVars, vnames, offs, types, 
		 options.treemodeOutput);
      Deque<DFA *>::iterator i;
      Deque<char *>::iterator j;
      for (i = dfalist.begin(), j = verifytitlelist->begin(); 
	   i != dfalist.end(); i++, j++) {
	cout << "\nFormula " << *j << ":\n";
	dfaAnalyze(*i, numVars, vnames, offs, types, 
		   options.treemodeOutput);
      }
    }
    else {
      if (numTypes == 0 || options.treemodeOutput) {
	if (!gtalist.empty())
	  cout << "Main formula:\n";
	gtaAnalyze(gta, numVars, vnames, offs,
		   options.graphvizSatisfyingEx,
		   options.graphvizCounterEx);
	Deque<GTA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = gtalist.begin(), j = verifytitlelist->begin(); 
	     i != gtalist.end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  gtaAnalyze(*i, numVars, vnames, offs,
		     options.graphvizSatisfyingEx,
		     options.graphvizCounterEx);
	}
      }
      else {
	if (options.graphvizSatisfyingEx ||
	    options.graphvizCounterEx)
	  cout << "Graphviz output of typed trees not implemented.\n";
	if (!gtalist.empty())
	  cout << "Main formula:\n";
	gtaTypeAnalyze(gta, numVars, vnames, types, offs, univs, trees);
	Deque<GTA *>::iterator i;
	Deque<char *>::iterator j;
	for (i = gtalist.begin(), j = verifytitlelist->begin(); 
	     i != gtalist.end(); i++, j++) {
	  cout << "\nFormula " << *j << ":\n";
	  gtaTypeAnalyze(*i, numVars, vnames, types, offs, univs, trees);
	}
      }
    }
  }

  ///////// CLEAN UP ///////////////////////////////////////////////////////

  if (options.mode != TREE) {
    dfaFree(dfa);
    for (Deque<DFA *>::iterator i = dfalist.begin(); i != dfalist.end(); i++)
      dfaFree(*i);
  }
  else {
    gtaFree(gta);
    for (Deque<GTA *>::iterator i = gtalist.begin(); i != gtalist.end(); i++)
      gtaFree(*i);
    freeGuide();
  }
  delete verifytitlelist;

  Deque<FileSource *>::iterator i;
  for (i = source.begin(); i != source.end(); i++)
    delete *i;
  
  for (ix = 0; ix < numVars; ix++) {
    delete[] univs[ix];
    mem_free(statespaces[ix]);
  }
  delete[] statespaces;
  delete[] vnames;
  delete[] offs;
  delete[] types;
  delete[] univs;
  delete[] trees;
  freeTreetypes();
    
  if (options.statistics)
    print_statistics();

  if (options.time) {
    timer_total.stop();
    cout << "\nTotal time:     ";
    timer_total.print();
    print_timing();
  }
  else if (options.printProgress) { 
    timer_total.stop();
    cout << "\nTotal time: ";
    timer_total.print();
  }
#ifdef MAXALLOCATED
  cout << "Maximum space allocated: " << (maxallocated+524288)/1048576 << " MB\n";
#endif
}
Esempio n. 22
0
bool
ModuleGenerator::finishCodegen()
{
    masm_.haltingAlign(CodeAlignment);
    uint32_t offsetInWhole = masm_.size();

    uint32_t numFuncExports = metadata_->funcExports.length();
    MOZ_ASSERT(numFuncExports == exportedFuncs_.count());

    // Generate stubs in a separate MacroAssembler since, otherwise, for modules
    // larger than the JumpImmediateRange, even local uses of Label will fail
    // due to the large absolute offsets temporarily stored by Label::bind().

    OffsetVector entries;
    ProfilingOffsetVector interpExits;
    ProfilingOffsetVector jitExits;
    TrapExitOffsetArray trapExits;
    Offsets outOfBoundsExit;
    Offsets unalignedAccessExit;
    Offsets interruptExit;
    Offsets throwStub;

    {
        TempAllocator alloc(&lifo_);
        MacroAssembler masm(MacroAssembler::WasmToken(), alloc);
        Label throwLabel;

        if (!entries.resize(numFuncExports))
            return false;
        for (uint32_t i = 0; i < numFuncExports; i++)
            entries[i] = GenerateEntry(masm, metadata_->funcExports[i]);

        if (!interpExits.resize(numFuncImports()))
            return false;
        if (!jitExits.resize(numFuncImports()))
            return false;
        for (uint32_t i = 0; i < numFuncImports(); i++) {
            interpExits[i] = GenerateImportInterpExit(masm, metadata_->funcImports[i], i, &throwLabel);
            jitExits[i] = GenerateImportJitExit(masm, metadata_->funcImports[i], &throwLabel);
        }

        for (Trap trap : MakeEnumeratedRange(Trap::Limit))
            trapExits[trap] = GenerateTrapExit(masm, trap, &throwLabel);

        outOfBoundsExit = GenerateOutOfBoundsExit(masm, &throwLabel);
        unalignedAccessExit = GenerateUnalignedExit(masm, &throwLabel);
        interruptExit = GenerateInterruptExit(masm, &throwLabel);
        throwStub = GenerateThrowStub(masm, &throwLabel);

        if (masm.oom() || !masm_.asmMergeWith(masm))
            return false;
    }

    // Adjust each of the resulting Offsets (to account for being merged into
    // masm_) and then create code ranges for all the stubs.

    for (uint32_t i = 0; i < numFuncExports; i++) {
        entries[i].offsetBy(offsetInWhole);
        metadata_->funcExports[i].initEntryOffset(entries[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::Entry, entries[i]))
            return false;
    }

    for (uint32_t i = 0; i < numFuncImports(); i++) {
        interpExits[i].offsetBy(offsetInWhole);
        metadata_->funcImports[i].initInterpExitOffset(interpExits[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::ImportInterpExit, interpExits[i]))
            return false;

        jitExits[i].offsetBy(offsetInWhole);
        metadata_->funcImports[i].initJitExitOffset(jitExits[i].begin);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::ImportJitExit, jitExits[i]))
            return false;
    }

    for (Trap trap : MakeEnumeratedRange(Trap::Limit)) {
        trapExits[trap].offsetBy(offsetInWhole);
        if (!metadata_->codeRanges.emplaceBack(CodeRange::TrapExit, trapExits[trap]))
            return false;
    }

    outOfBoundsExit.offsetBy(offsetInWhole);
    if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, outOfBoundsExit))
        return false;

    unalignedAccessExit.offsetBy(offsetInWhole);
    if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, unalignedAccessExit))
        return false;

    interruptExit.offsetBy(offsetInWhole);
    if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, interruptExit))
        return false;

    throwStub.offsetBy(offsetInWhole);
    if (!metadata_->codeRanges.emplaceBack(CodeRange::Inline, throwStub))
        return false;

    // Fill in LinkData with the offsets of these stubs.

    linkData_.outOfBoundsOffset = outOfBoundsExit.begin;
    linkData_.interruptOffset = interruptExit.begin;

    // Now that all other code has been emitted, patch all remaining callsites.

    if (!patchCallSites(&trapExits))
        return false;

    // Now that all code has been generated, patch far jumps to destinations.

    for (CallThunk& callThunk : metadata_->callThunks) {
        uint32_t funcIndex = callThunk.u.funcIndex;
        callThunk.u.codeRangeIndex = funcToCodeRange_[funcIndex];
        CodeOffset farJump(callThunk.offset);
        masm_.patchFarJump(farJump, funcCodeRange(funcIndex).funcNonProfilingEntry());
    }

    for (const TrapFarJump& farJump : masm_.trapFarJumps())
        masm_.patchFarJump(farJump.jump, trapExits[farJump.trap].begin);

    // Code-generation is complete!

    masm_.finish();
    return !masm_.oom();
}