Exemplo n.º 1
0
    int32 * TextbookBoyerMooreSetup<C>::GetGoodSuffix(ArenaAllocator* allocator, const Char * pat, CharCount patLen, int skip)
    {
        // pat offset q |-> longest prefix of pat which is a proper suffix of pat[0..q]
        // (thanks to equivalence classes being in canonical order we only need to look at the first
        //  character of each skip grouping in the pattern)
        int32* prefix = AnewArray(allocator, int32, patLen);
        prefix[0] = 0;
        int32 k = 0;
        for (CharCount q = 1; q < patLen; q++)
        {
            while (k > 0 && pat[k * skip] != pat[q * skip])
                k = prefix[k - 1];
            if (pat[k * skip] == pat[q * skip])
                k++;
            prefix[q] = k;
        }

        // As above, but for rev(pat)
        int32* revPrefix = AnewArray(allocator, int32, patLen);
        revPrefix[0] = 0;
        k = 0;
        for (CharCount q = 1; q < patLen; q++)
        {
            while (k > 0 && pat[(patLen - k - 1) * skip] != pat[(patLen - q - 1) * skip])
                k = revPrefix[k - 1];
            if (pat[(patLen - k - 1) * skip] == pat[(patLen - q - 1) * skip])
                k++;
            revPrefix[q] = k;
        }

        // pat prefix length l |-> least shift s.t. pat[0..l-1] is not mismatched
        int32 * goodSuffix = AnewArray(allocator, int32, patLen + 1);
        for (CharCount j = 0; j <= patLen; j++)
            goodSuffix[j] = patLen - prefix[patLen - 1];
        for (CharCount l = 1; l <= patLen; l++)
        {
            CharCount j = patLen - revPrefix[l - 1];
            int32 s = l - revPrefix[l - 1];
            if (goodSuffix[j] > s)
                goodSuffix[j] = s;
        }
        // shift above one to the left
        for (CharCount j = 0; j < patLen; j++)
            goodSuffix[j] = goodSuffix[j + 1];

        AdeleteArray(allocator, patLen, prefix);
        AdeleteArray(allocator, patLen, revPrefix);

        return goodSuffix;
    }
Exemplo n.º 2
0
 void
 WasmElementSegment::Init(const Js::WebAssemblyModule& module)
 {
     Assert(m_numElem > 0);
     m_elems = AnewArray(m_alloc, UINT32, m_numElem);
     memset(m_elems, Js::Constants::UninitializedValue, m_numElem * sizeof(UINT32));
 }
    const StElemInfo *ReadOnlyDynamicProfileInfo::GetStElemInfo(FunctionBody *functionBody, ProfileId stElemId)
    {
        Assert(functionBody);
        Assert(stElemId < functionBody->GetProfiledStElemCount());

        // This data is accessed multiple times. Since the original profile data may be changing on the foreground thread,
        // the first time it's accessed it will be copied from the original profile data (if we're jitting in the
        // background).
        if(!stElemInfo)
        {
            if(backgroundAllocator)
            {
                // Jitting in the background
                StElemInfo *const info = AnewArray(backgroundAllocator, StElemInfo, functionBody->GetProfiledStElemCount());
                js_memcpy_s(
                    info,
                    functionBody->GetProfiledStElemCount() * sizeof(info[0]),
                    profileInfo->GetStElemInfo(),
                    functionBody->GetProfiledStElemCount() * sizeof(info[0]));
                stElemInfo = info;
            }
            else
            {
                // Jitting in the foreground
                stElemInfo = profileInfo->GetStElemInfo();
            }
        }
        return &stElemInfo[stElemId];
    }
Exemplo n.º 4
0
    Var JavascriptSIMDObject::ToString(ScriptContext* scriptContext) const
    {
        Assert(scriptContext);
        Assert(typeDescriptor != TypeIds_SIMDObject);

        BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
        char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
        SIMDValue simdValue;
        switch (typeDescriptor)
        {
        case TypeIds_SIMDBool8x16:
            simdValue = JavascriptSIMDBool8x16::FromVar(value)->GetValue();
            JavascriptSIMDBool8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDInt8x16:
            simdValue = JavascriptSIMDInt8x16::FromVar(value)->GetValue();
            JavascriptSIMDInt8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDUint8x16:
            simdValue = JavascriptSIMDUint8x16::FromVar(value)->GetValue();
            JavascriptSIMDUint8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDBool16x8:
            simdValue = JavascriptSIMDBool16x8::FromVar(value)->GetValue();
            JavascriptSIMDBool16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDInt16x8:
            simdValue = JavascriptSIMDInt16x8::FromVar(value)->GetValue();
            JavascriptSIMDInt16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDUint16x8:
            simdValue = JavascriptSIMDUint16x8::FromVar(value)->GetValue();
            JavascriptSIMDUint16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDBool32x4:
            simdValue = JavascriptSIMDBool32x4::FromVar(value)->GetValue();
            JavascriptSIMDBool32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDInt32x4:
            simdValue = JavascriptSIMDInt32x4::FromVar(value)->GetValue();
            JavascriptSIMDInt32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDUint32x4:
            simdValue = JavascriptSIMDUint32x4::FromVar(value)->GetValue();
            JavascriptSIMDUint32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        case TypeIds_SIMDFloat32x4:
            simdValue = JavascriptSIMDFloat32x4::FromVar(value)->GetValue();
            JavascriptSIMDFloat32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
            break;
        default:
            Assert(UNREACHED);
        }
        JavascriptString* string = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());
        END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
        return string;
    }
Exemplo n.º 5
0
void JSONScanner::BuildUnescapedString(bool shouldSkipLastCharacter)
{
    AssertMsg(this->allocator != nullptr, "We must have built the allocator");
    AssertMsg(this->currentRangeCharacterPairList != nullptr, "We must have built the currentRangeCharacterPairList");
    AssertMsg(this->currentRangeCharacterPairList->Count() > 0, "We need to build the current string only because we have escaped characters");

    // Step 1: Ensure the buffer has sufficient space
    int requiredSize = this->GetCurrentStringLen();
    if (requiredSize > this->stringBufferLength)
    {
        if (this->stringBuffer)
        {
            AdeleteArray(this->allocator, this->stringBufferLength, this->stringBuffer);
            this->stringBuffer = nullptr;
        }

        this->stringBuffer = AnewArray(this->allocator, char16, requiredSize);
        this->stringBufferLength = requiredSize;
    }

    // Step 2: Copy the data to the buffer
    int totalCopied = 0;
    char16* begin_copy = this->stringBuffer;
    int lastCharacterIndex = this->currentRangeCharacterPairList->Count() - 1;
    for (int i = 0; i <= lastCharacterIndex; i++)
    {
        RangeCharacterPair data = this->currentRangeCharacterPairList->Item(i);
        int charactersToCopy = data.m_rangeLength;
        js_wmemcpy_s(begin_copy, charactersToCopy, this->inputText + data.m_rangeStart, charactersToCopy);
        begin_copy += charactersToCopy;
        totalCopied += charactersToCopy;

        if (i == lastCharacterIndex && shouldSkipLastCharacter)
        {
            continue;
        }

        *begin_copy = data.m_char;
        begin_copy++;
        totalCopied++;
    }

    if (totalCopied != requiredSize)
    {
        OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): allocated size = %d != copying size %d\n"), requiredSize, totalCopied);
        AssertMsg(totalCopied == requiredSize, "BuildUnescapedString(): The allocated size and copying size should match.");
    }

    OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): unescaped string as '%.*s'\n"), GetCurrentStringLen(), this->stringBuffer);
}
Exemplo n.º 6
0
 void RuntimeCharTrie::CloneFrom(ArenaAllocator* allocator, const CharTrie& other)
 {
     count = other.count;
     if (count > 0)
     {
         children = AnewArray(allocator, RuntimeCharTrieEntry, count);
         for (int i = 0; i < count; i++)
         {
             children[i].c = other.children[i].c;
             children[i].node.CloneFrom(allocator,  other.children[i].node);
         }
     }
     else
         children = 0;
 }
Exemplo n.º 7
0
char16* NarrowStringToWide(Context* ctx, const char* src, const size_t* srcSize = nullptr, charcount_t* dstSize = nullptr)
{
    auto allocator = [&ctx](size_t size) {return (char16*)AnewArray(ctx->allocator, char16, size); };
    char16* dst = nullptr;
    charcount_t size;
    HRESULT hr = utf8::NarrowStringToWide(allocator, src, srcSize ? *srcSize : strlen(src), &dst, &size);
    if (hr != S_OK)
    {
        JavascriptError::ThrowOutOfMemoryError(ctx->scriptContext);
    }
    if (dstSize)
    {
        *dstSize = size;
    }
    return dst;
}
Exemplo n.º 8
0
    void MemoryLogger::Write(const char16* msg)
    {
#ifdef EXCEPTION_CHECK
        // In most cases this will be called at runtime when we have exception check enabled.
        AutoNestedHandledExceptionType autoNestedHandledExceptionType(ExceptionType_DisableCheck);
#endif
        AutoCriticalSection autocs(&m_criticalSection); // TODO: with circular buffer now we can use much granular lock.

        // Create a copy of the message.
        size_t len = wcslen(msg);
        char16* buf = AnewArray(m_alloc, char16, len + 1);
        js_wmemcpy_s(buf, len + 1, msg, len + 1);   // Copy with the NULL-terminator.

        // m_current is the next position to write to.
        if (m_log[m_current])
        {
            Adelete(m_alloc, m_log[m_current]);
        }
        m_log[m_current] = buf;
        m_current = (m_current + 1) % m_capacity;
    }
Exemplo n.º 9
0
            _u("Reset"),
            _u("Count"));

    Output::Print(_u("--------------------------------------------------------------------------------------------------------\n"));
}

int MemoryProfiler::CreateArenaUsageSummary(ArenaAllocator * alloc, bool liveOnly,
    _Outptr_result_buffer_(return) LPWSTR ** name_ptr, _Outptr_result_buffer_(return) ArenaMemoryDataSummary *** summaries_ptr)
{
    Assert(alloc);

    LPWSTR *& name = *name_ptr;
    ArenaMemoryDataSummary **& summaries = *summaries_ptr;

    int count = arenaDataMap.Count();
    name = AnewArray(alloc, LPWSTR, count);
    int i = 0;
    arenaDataMap.Map([&i, name](LPWSTR key, ArenaMemoryDataSummary*)
    {
        name[i++] = key;
    });
    JsUtil::QuickSort<LPWSTR, DefaultComparer<LPWSTR>>::Sort(name, name + (count - 1));

    summaries = AnewArray(alloc, ArenaMemoryDataSummary *, count);

    for (int i = 0; i < count; i++)
    {
        ArenaMemoryDataSummary * summary = arenaDataMap.Item(name[i]);
        ArenaMemoryData * data = summary->data;

        ArenaMemoryDataSummary * localSummary;
Exemplo n.º 10
0
    void* AsmJsEncoder::Encode( FunctionBody* functionBody )
    {
        Assert( functionBody );
        mFunctionBody = functionBody;
#if DBG_DUMP
        AsmJsJitTemplate::Globals::CurrentEncodingFunction = mFunctionBody;
#endif
        AsmJsFunctionInfo* asmInfo = functionBody->GetAsmJsFunctionInfo();
        FunctionEntryPointInfo* entryPointInfo = ((FunctionEntryPointInfo*)(functionBody->GetDefaultEntryPointInfo()));
        // number of var on the stack + ebp + eip
        mIntOffset = asmInfo->GetIntByteOffset() + GetOffset<Var>();
        mDoubleOffset = asmInfo->GetDoubleByteOffset() + GetOffset<Var>();
        mFloatOffset = asmInfo->GetFloatByteOffset() + GetOffset<Var>();
        mSimdOffset = asmInfo->GetSimdByteOffset() + GetOffset<Var>();

        NoRecoverMemoryArenaAllocator localAlloc(_u("BE-AsmJsEncoder"), GetPageAllocator(), Js::Throw::OutOfMemory);
        mLocalAlloc = &localAlloc;

        mRelocLabelMap = Anew( mLocalAlloc, RelocLabelMap, mLocalAlloc );
        mTemplateData = AsmJsJitTemplate::InitTemplateData();
        mEncodeBufferSize = GetEncodeBufferSize(functionBody);
        mEncodeBuffer = AnewArray((&localAlloc), BYTE, mEncodeBufferSize);
        mPc = mEncodeBuffer;
        mReader.Create( functionBody );
        ip = mReader.GetIP();

#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
        if( PHASE_TRACE( Js::AsmjsEncoderPhase, mFunctionBody ) )
        {
            Output::Print( _u("\n\n") );
            functionBody->DumpFullFunctionName();
            Output::Print( _u("\n StackSize = %d , Offsets: Var = %d, Int = %d, Double = %d\n"), mFunctionBody->GetAsmJsFunctionInfo()->GetTotalSizeinBytes(), GetOffset<Var>(), GetOffset<int>(), GetOffset<double>() );
        }
#endif

        AsmJsJitTemplate::FunctionEntry::ApplyTemplate( this, mPc );
        while( ReadOp() ){}
        AsmJsJitTemplate::FunctionExit::ApplyTemplate( this, mPc );

        AsmJsJitTemplate::FreeTemplateData( mTemplateData );
#if DBG_DUMP
        AsmJsJitTemplate::Globals::CurrentEncodingFunction = nullptr;
#endif
        ApplyRelocs();

        ptrdiff_t codeSize = mPc - mEncodeBuffer;
        if( codeSize > 0 )
        {
            Assert( ::Math::FitsInDWord( codeSize ) );

            BYTE *buffer;
            EmitBufferAllocation *allocation = GetCodeGenAllocator()->emitBufferManager.AllocateBuffer( codeSize, &buffer, 0, 0 );
            functionBody->GetAsmJsFunctionInfo()->mTJBeginAddress = buffer;

            if (buffer == nullptr)
            {
                Js::Throw::OutOfMemory();
            }

            if (!GetCodeGenAllocator()->emitBufferManager.CommitBuffer(allocation, buffer, codeSize, mEncodeBuffer))
            {
                Js::Throw::OutOfMemory();
            }

            functionBody->GetScriptContext()->GetThreadContext()->SetValidCallTargetForCFG(buffer);

            // TODO: improve this once EntryPoint cleanup work is complete!
#if 0
            const char16 *const functionName = functionBody->GetDisplayName();
            const char16 *const suffix = _u("TJ");
            char16 functionNameArray[256];
            const size_t functionNameCharLength = functionBody->GetDisplayNameLength();
            wcscpy_s(functionNameArray, 256, functionName);
            wcscpy_s(&functionNameArray[functionNameCharLength], 256 - functionNameCharLength, suffix);
#endif
            JS_ETW(EventWriteMethodLoad(functionBody->GetScriptContext(),
                (void *)buffer,
                codeSize,
                EtwTrace::GetFunctionId(functionBody),
                0 /* methodFlags - for future use*/,
                MethodType_Jit,
                EtwTrace::GetSourceId(functionBody),
                functionBody->GetLineNumber(),
                functionBody->GetColumnNumber(),
                functionBody->GetDisplayName()));
            entryPointInfo->SetTJCodeGenDone(); // set the codegen to done state for TJ
            entryPointInfo->SetCodeSize(codeSize);
            return buffer;
        }
        return nullptr;
    }
Exemplo n.º 11
0
 StringProfiler::HistogramIndex::HistogramIndex( ArenaAllocator* allocator, uint size )
 {
     this->index = AnewArray(allocator, UintUintPair, size);
     this->count = 0;
 }
Exemplo n.º 12
0
///----------------------------------------------------------------------------
///
/// Encoder::Encode
///
///     Main entrypoint of encoder.  Encode each IR instruction into the
///     appropriate machine encoding.
///
///----------------------------------------------------------------------------
void
Encoder::Encode()
{
    NoRecoverMemoryArenaAllocator localAlloc(_u("BE-Encoder"), m_func->m_alloc->GetPageAllocator(), Js::Throw::OutOfMemory);
    m_tempAlloc = &localAlloc;

    uint32 instrCount = m_func->GetInstrCount();
    size_t totalJmpTableSizeInBytes = 0;

    JmpTableList * jumpTableListForSwitchStatement = nullptr;

    m_encoderMD.Init(this);
    m_encodeBufferSize = UInt32Math::Mul(instrCount, MachMaxInstrSize);
    m_encodeBufferSize += m_func->m_totalJumpTableSizeInBytesForSwitchStatements;
    m_encodeBuffer = AnewArray(m_tempAlloc, BYTE, m_encodeBufferSize);
#if DBG_DUMP
    m_instrNumber = 0;
    m_offsetBuffer = AnewArray(m_tempAlloc, uint, instrCount);
#endif

    m_pragmaInstrToRecordMap    = Anew(m_tempAlloc, PragmaInstrList, m_tempAlloc);
    if (DoTrackAllStatementBoundary())
    {
        // Create a new list, if we are tracking all statement boundaries.
        m_pragmaInstrToRecordOffset = Anew(m_tempAlloc, PragmaInstrList, m_tempAlloc);
    }
    else
    {
        // Set the list to the same as the throw map list, so that processing of the list
        // of pragma are done on those only.
        m_pragmaInstrToRecordOffset = m_pragmaInstrToRecordMap;
    }

#if defined(_M_IX86) || defined(_M_X64)
    // for BR shortening
    m_inlineeFrameRecords       = Anew(m_tempAlloc, InlineeFrameRecords, m_tempAlloc);
#endif

    m_pc = m_encodeBuffer;
    m_inlineeFrameMap = Anew(m_tempAlloc, InlineeFrameMap, m_tempAlloc);
    m_bailoutRecordMap = Anew(m_tempAlloc, BailoutRecordMap, m_tempAlloc);

    IR::PragmaInstr* pragmaInstr = nullptr;
    uint32 pragmaOffsetInBuffer = 0;

#ifdef _M_X64
    bool inProlog = false;
#endif
    bool isCallInstr = false;

    FOREACH_INSTR_IN_FUNC(instr, m_func)
    {
        Assert(Lowerer::ValidOpcodeAfterLower(instr, m_func));

        if (GetCurrentOffset() + MachMaxInstrSize < m_encodeBufferSize)
        {
            ptrdiff_t count;

#if DBG_DUMP
            AssertMsg(m_instrNumber < instrCount, "Bad instr count?");
            __analysis_assume(m_instrNumber < instrCount);
            m_offsetBuffer[m_instrNumber++] = GetCurrentOffset();
#endif
            if (instr->IsPragmaInstr())
            {
                switch(instr->m_opcode)
                {
#ifdef _M_X64
                case Js::OpCode::PrologStart:
                    m_func->m_prologEncoder.Begin(m_pc - m_encodeBuffer);
                    inProlog = true;
                    continue;

                case Js::OpCode::PrologEnd:
                    m_func->m_prologEncoder.End();
                    inProlog = false;
                    continue;
#endif
                case Js::OpCode::StatementBoundary:
                    pragmaOffsetInBuffer = GetCurrentOffset();
                    pragmaInstr = instr->AsPragmaInstr();
                    pragmaInstr->m_offsetInBuffer = pragmaOffsetInBuffer;

                    // will record after BR shortening with adjusted offsets
                    if (DoTrackAllStatementBoundary())
                    {
                        m_pragmaInstrToRecordOffset->Add(pragmaInstr);
                    }

                    break;

                default:
                    continue;
                }
            }
            else if (instr->IsBranchInstr() && instr->AsBranchInstr()->IsMultiBranch())
            {
                Assert(instr->GetSrc1() && instr->GetSrc1()->IsRegOpnd());
                IR::MultiBranchInstr * multiBranchInstr = instr->AsBranchInstr()->AsMultiBrInstr();

                if (multiBranchInstr->m_isSwitchBr &&
                        (multiBranchInstr->m_kind == IR::MultiBranchInstr::IntJumpTable || multiBranchInstr->m_kind == IR::MultiBranchInstr::SingleCharStrJumpTable))
                {
                    BranchJumpTableWrapper * branchJumpTableWrapper = multiBranchInstr->GetBranchJumpTable();
                    if (jumpTableListForSwitchStatement == nullptr)
                    {
                        jumpTableListForSwitchStatement = Anew(m_tempAlloc, JmpTableList, m_tempAlloc);
                    }
                    jumpTableListForSwitchStatement->Add(branchJumpTableWrapper);

                    totalJmpTableSizeInBytes += (branchJumpTableWrapper->tableSize * sizeof(void*));
                }
                else
                {
                    //Reloc Records
                    EncoderMD * encoderMD = &(this->m_encoderMD);
                    multiBranchInstr->MapMultiBrTargetByAddress([=](void ** offset) -> void
                    {
#if defined(_M_ARM32_OR_ARM64)
                        encoderMD->AddLabelReloc((byte*) offset);
#else
                        encoderMD->AppendRelocEntry(RelocTypeLabelUse, (void*) (offset));
#endif
                    });
                }
            }
            else
            {
                isCallInstr = LowererMD::IsCall(instr);
                if (pragmaInstr && (instr->isInlineeEntryInstr || isCallInstr))
                {
                    // will record throw map after BR shortening with adjusted offsets
                    m_pragmaInstrToRecordMap->Add(pragmaInstr);
                    pragmaInstr = nullptr; // Only once per pragma instr -- do we need to make this record?
                }

                if (instr->HasBailOutInfo())
                {
                    Assert(this->m_func->hasBailout);
                    Assert(LowererMD::IsCall(instr));
                    instr->GetBailOutInfo()->FinalizeBailOutRecord(this->m_func);
                }

                if (instr->isInlineeEntryInstr)
                {

                    m_encoderMD.EncodeInlineeCallInfo(instr, GetCurrentOffset());
                }

                if (instr->m_opcode == Js::OpCode::InlineeStart)
                {
                    Assert(!instr->isInlineeEntryInstr);
                    if (pragmaInstr)
                    {
                        m_pragmaInstrToRecordMap->Add(pragmaInstr);
                        pragmaInstr = nullptr;
                    }
                    Func* inlinee = instr->m_func;
                    if (inlinee->frameInfo && inlinee->frameInfo->record)
                    {
                        inlinee->frameInfo->record->Finalize(inlinee, GetCurrentOffset());

#if defined(_M_IX86) || defined(_M_X64)
                        // Store all records to be adjusted for BR shortening
                        m_inlineeFrameRecords->Add(inlinee->frameInfo->record);
#endif
                    }
                    continue;
                }
            }

            count = m_encoderMD.Encode(instr, m_pc, m_encodeBuffer);

#if DBG_DUMP
            if (PHASE_TRACE(Js::EncoderPhase, this->m_func))
            {
                instr->Dump((IRDumpFlags)(IRDumpFlags_SimpleForm | IRDumpFlags_SkipEndLine | IRDumpFlags_SkipByteCodeOffset));
                Output::SkipToColumn(80);
                for (BYTE * current = m_pc; current < m_pc + count; current++)
                {
                    Output::Print(_u("%02X "), *current);
                }
                Output::Print(_u("\n"));
                Output::Flush();
            }
#endif
#ifdef _M_X64
            if (inProlog)
                m_func->m_prologEncoder.EncodeInstr(instr, count & 0xFF);
#endif
            m_pc += count;

#if defined(_M_IX86) || defined(_M_X64)
            // for BR shortening.
            if (instr->isInlineeEntryInstr)
                m_encoderMD.AppendRelocEntry(RelocType::RelocTypeInlineeEntryOffset, (void*) (m_pc - MachPtr));
#endif
            if (isCallInstr)
            {
                isCallInstr = false;
                this->RecordInlineeFrame(instr->m_func, GetCurrentOffset());
            }
            if (instr->HasBailOutInfo() && Lowerer::DoLazyBailout(this->m_func))
            {
                this->RecordBailout(instr, (uint32)(m_pc - m_encodeBuffer));
            }
        }
        else
        {
            Fatal();
        }
    }
Exemplo n.º 13
0
/* static */
void
JITTimeProfileInfo::InitializeJITProfileData(
    __in ArenaAllocator * alloc,
    __in Js::DynamicProfileInfo * profileInfo,
    __in Js::FunctionBody *functionBody,
    __out ProfileDataIDL * data,
    bool isForegroundJIT)
{
    if (profileInfo == nullptr)
    {
        return;
    }

    CompileAssert(sizeof(LdElemIDL) == sizeof(Js::LdElemInfo));
    CompileAssert(sizeof(StElemIDL) == sizeof(Js::StElemInfo));

    data->profiledLdElemCount = functionBody->GetProfiledLdElemCount();
    data->profiledStElemCount = functionBody->GetProfiledStElemCount();

    if (JITManager::GetJITManager()->IsOOPJITEnabled() || isForegroundJIT)
    {
        data->ldElemData = (LdElemIDL*)profileInfo->GetLdElemInfo();
        data->stElemData = (StElemIDL*)profileInfo->GetStElemInfo();
    }
    else
    {
        // for in-proc background JIT we need to explicitly copy LdElem and StElem info
        data->ldElemData = AnewArray(alloc, LdElemIDL, data->profiledLdElemCount);
        memcpy_s(
            data->ldElemData,
            data->profiledLdElemCount * sizeof(LdElemIDL),
            profileInfo->GetLdElemInfo(),
            functionBody->GetProfiledLdElemCount() * sizeof(Js::LdElemInfo)
        );

        data->stElemData = AnewArray(alloc, StElemIDL, data->profiledStElemCount);
        memcpy_s(
            data->stElemData,
            data->profiledStElemCount * sizeof(StElemIDL),
            profileInfo->GetStElemInfo(),
            functionBody->GetProfiledStElemCount() * sizeof(Js::StElemInfo)
        );
    }

    CompileAssert(sizeof(ArrayCallSiteIDL) == sizeof(Js::ArrayCallSiteInfo));
    data->profiledArrayCallSiteCount = functionBody->GetProfiledArrayCallSiteCount();
    data->arrayCallSiteData = (ArrayCallSiteIDL*)profileInfo->GetArrayCallSiteInfo();
    data->arrayCallSiteDataAddr = (intptr_t)profileInfo->GetArrayCallSiteInfo();

    CompileAssert(sizeof(FldIDL) == sizeof(Js::FldInfo));
    data->inlineCacheCount = functionBody->GetProfiledFldCount();
    data->fldData = (FldIDL*)profileInfo->GetFldInfo();
    data->fldDataAddr = (intptr_t)profileInfo->GetFldInfo();

    CompileAssert(sizeof(ThisIDL) == sizeof(Js::ThisInfo));
    data->thisData = *reinterpret_cast<ThisIDL*>(&profileInfo->GetThisInfo());

    CompileAssert(sizeof(CallSiteIDL) == sizeof(Js::CallSiteInfo));
    data->profiledCallSiteCount = functionBody->GetProfiledCallSiteCount();
    data->callSiteData = reinterpret_cast<CallSiteIDL*>(profileInfo->GetCallSiteInfo());

    CompileAssert(sizeof(BVUnitIDL) == sizeof(BVUnit));
    data->loopFlags = (BVFixedIDL*)profileInfo->GetLoopFlags();

    CompileAssert(sizeof(ValueType) == sizeof(uint16));

    data->profiledSlotCount = functionBody->GetProfiledSlotCount();
    data->slotData = reinterpret_cast<uint16*>(profileInfo->GetSlotInfo());

    data->profiledReturnTypeCount = functionBody->GetProfiledReturnTypeCount();
    data->returnTypeData = reinterpret_cast<uint16*>(profileInfo->GetReturnTypeInfo());

    data->profiledDivOrRemCount = functionBody->GetProfiledDivOrRemCount();
    data->divideTypeInfo = reinterpret_cast<uint16*>(profileInfo->GetDivideTypeInfo());

    data->profiledSwitchCount = functionBody->GetProfiledSwitchCount();
    data->switchTypeInfo = reinterpret_cast<uint16*>(profileInfo->GetSwitchTypeInfo());

    data->profiledInParamsCount = functionBody->GetProfiledInParamsCount();
    data->parameterInfo = reinterpret_cast<uint16*>(profileInfo->GetParameterInfo());

    data->loopCount = functionBody->GetLoopCount();
    data->loopImplicitCallFlags = reinterpret_cast<byte*>(profileInfo->GetLoopImplicitCallFlags());

    data->implicitCallFlags = static_cast<byte>(profileInfo->GetImplicitCallFlags());

    data->flags = 0;
    data->flags |= profileInfo->IsAggressiveIntTypeSpecDisabled(false) ? Flags_disableAggressiveIntTypeSpec : 0;
    data->flags |= profileInfo->IsAggressiveIntTypeSpecDisabled(true) ? Flags_disableAggressiveIntTypeSpec_jitLoopBody : 0;
    data->flags |= profileInfo->IsAggressiveMulIntTypeSpecDisabled(false) ? Flags_disableAggressiveMulIntTypeSpec : 0;
    data->flags |= profileInfo->IsAggressiveMulIntTypeSpecDisabled(true) ? Flags_disableAggressiveMulIntTypeSpec_jitLoopBody : 0;
    data->flags |= profileInfo->IsDivIntTypeSpecDisabled(false) ? Flags_disableDivIntTypeSpec : 0;
    data->flags |= profileInfo->IsDivIntTypeSpecDisabled(true) ? Flags_disableDivIntTypeSpec_jitLoopBody : 0;
    data->flags |= profileInfo->IsLossyIntTypeSpecDisabled() ? Flags_disableLossyIntTypeSpec : 0;
    data->flags |= profileInfo->IsTrackCompoundedIntOverflowDisabled() ? Flags_disableTrackCompoundedIntOverflow : 0;
    data->flags |= profileInfo->IsFloatTypeSpecDisabled() ? Flags_disableFloatTypeSpec : 0;
    data->flags |= profileInfo->IsArrayCheckHoistDisabled(false) ? Flags_disableArrayCheckHoist : 0;
    data->flags |= profileInfo->IsArrayCheckHoistDisabled(true) ? Flags_disableArrayCheckHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsArrayMissingValueCheckHoistDisabled(false) ? Flags_disableArrayMissingValueCheckHoist : 0;
    data->flags |= profileInfo->IsArrayMissingValueCheckHoistDisabled(true) ? Flags_disableArrayMissingValueCheckHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsJsArraySegmentHoistDisabled(false) ? Flags_disableJsArraySegmentHoist : 0;
    data->flags |= profileInfo->IsJsArraySegmentHoistDisabled(true) ? Flags_disableJsArraySegmentHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsArrayLengthHoistDisabled(false) ? Flags_disableArrayLengthHoist : 0;
    data->flags |= profileInfo->IsArrayLengthHoistDisabled(true) ? Flags_disableArrayLengthHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsTypedArrayTypeSpecDisabled(false) ? Flags_disableTypedArrayTypeSpec : 0;
    data->flags |= profileInfo->IsTypedArrayTypeSpecDisabled(true) ? Flags_disableTypedArrayTypeSpec_jitLoopBody : 0;
    data->flags |= profileInfo->IsLdLenIntSpecDisabled() ? Flags_disableLdLenIntSpec : 0;
    data->flags |= profileInfo->IsBoundCheckHoistDisabled(false) ? Flags_disableBoundCheckHoist : 0;
    data->flags |= profileInfo->IsBoundCheckHoistDisabled(true) ? Flags_disableBoundCheckHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsLoopCountBasedBoundCheckHoistDisabled(false) ? Flags_disableLoopCountBasedBoundCheckHoist : 0;
    data->flags |= profileInfo->IsLoopCountBasedBoundCheckHoistDisabled(true) ? Flags_disableLoopCountBasedBoundCheckHoist_jitLoopBody : 0;
    data->flags |= profileInfo->IsFloorInliningDisabled() ? Flags_disableFloorInlining : 0;
    data->flags |= profileInfo->IsNoProfileBailoutsDisabled() ? Flags_disableNoProfileBailouts : 0;
    data->flags |= profileInfo->IsSwitchOptDisabled() ? Flags_disableSwitchOpt : 0;
    data->flags |= profileInfo->IsEquivalentObjTypeSpecDisabled() ? Flags_disableEquivalentObjTypeSpec : 0;
    data->flags |= profileInfo->IsObjTypeSpecDisabledInJitLoopBody() ? Flags_disableObjTypeSpec_jitLoopBody : 0;
    data->flags |= profileInfo->IsMemOpDisabled() ? Flags_disableMemOp : 0;
    data->flags |= profileInfo->IsCheckThisDisabled() ? Flags_disableCheckThis : 0;
    data->flags |= profileInfo->HasLdFldCallSiteInfo() ? Flags_hasLdFldCallSiteInfo : 0;
    data->flags |= profileInfo->IsStackArgOptDisabled() ? Flags_disableStackArgOpt : 0;
    data->flags |= profileInfo->IsLoopImplicitCallInfoDisabled() ? Flags_disableLoopImplicitCallInfo : 0;
    data->flags |= profileInfo->IsPowIntIntTypeSpecDisabled() ? Flags_disablePowIntIntTypeSpec : 0;
}
Exemplo n.º 14
0
    Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString, const T (&laneValues)[N], 
        CallInfo* callInfo, ScriptContext* scriptContext) const
    {
        Assert(args);
        Assert(N == 4 || N == 8 || N == 16);
        if (typeDescriptor == TypeIds_SIMDBool8x16 ||
            typeDescriptor == TypeIds_SIMDBool16x8 ||
            typeDescriptor == TypeIds_SIMDBool32x4)
        {
            return ToString(scriptContext);   //Boolean types does not have toLocaleString.
        }

        // Creating a new arguments list for the JavascriptNumber generated from each lane.The optional SIMDToLocaleString Args are
        //added to this argument list. 
        Var* newArgs = HeapNewArray(Var, numArgs);
        switch (numArgs)
        {
        case 1:
            break;
        case 2:
            newArgs[1] = args[1];
            break;
        case 3:
            newArgs[1] = args[1];
            newArgs[2] = args[2];
            break;
        default:
            Assert(UNREACHED);
        }
        //Locale specifc seperator?? 
        JavascriptString *seperator = JavascriptString::NewWithSz(_u(", "), scriptContext);
        uint idx = 0;
        Var laneVar = nullptr;
        BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
        char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
        JavascriptString *result = nullptr;

        swprintf_s(stringBuffer, 1024, typeString);
        result = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());

        if (typeDescriptor == TypeIds_SIMDFloat32x4)
        {
            for (; idx < numLanes - 1; ++idx)
            {
                laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
                newArgs[0] = laneVar;
                JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
                result = JavascriptString::Concat(result, laneValue);
                result = JavascriptString::Concat(result, seperator);
            }
            laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
            newArgs[0] = laneVar;
            result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
        }
        else if (typeDescriptor == TypeIds_SIMDInt8x16 || typeDescriptor == TypeIds_SIMDInt16x8 || typeDescriptor == TypeIds_SIMDInt32x4)
        {
            for (; idx < numLanes - 1; ++idx)
            {
                laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext); 
                newArgs[0] = laneVar;
                JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
                result = JavascriptString::Concat(result, laneValue);
                result = JavascriptString::Concat(result, seperator);
            }
            laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext);
            newArgs[0] = laneVar;
            result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
        }
        else
        {
            Assert((typeDescriptor == TypeIds_SIMDUint8x16 || typeDescriptor == TypeIds_SIMDUint16x8 || typeDescriptor == TypeIds_SIMDUint32x4));
            for (; idx < numLanes - 1; ++idx)
            {
                laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext); 
                newArgs[0] = laneVar;
                JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
                result = JavascriptString::Concat(result, laneValue);
                result = JavascriptString::Concat(result, seperator);
            }
            laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext);
            newArgs[0] = laneVar;
            result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
        }
        HeapDeleteArray(numArgs, newArgs);
        END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
        return JavascriptString::Concat(result, JavascriptString::NewWithSz(_u(")"), scriptContext));
    }
Exemplo n.º 15
0
Js::Var WabtInterface::EntryConvertWast2Wasm(RecyclableObject* function, CallInfo callInfo, ...)
{
    ScriptContext* scriptContext = function->GetScriptContext();
    PROBE_STACK(function->GetScriptContext(), Constants::MinStackDefault);

    ARGUMENTS(args, callInfo);
    AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");

    Assert(!(callInfo.Flags & CallFlags_New));

    if (args.Info.Count < 2 || !JavascriptString::Is(args[1]))
    {
        JavascriptError::ThrowTypeError(scriptContext, WASMERR_NeedBufferSource);
    }
    bool isSpecText = false;
    if (args.Info.Count > 2)
    {
        // optional config object
        if (!JavascriptOperators::IsObject(args[2]))
        {
            JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedObject, _u("config"));
        }
        DynamicObject * configObject = JavascriptObject::FromVar(args[2]);

        Js::Var isSpecVar = JavascriptOperators::OP_GetProperty(configObject, PropertyIds::spec, scriptContext);
        isSpecText = JavascriptConversion::ToBool(isSpecVar, scriptContext);
    }

    ArenaAllocator arena(_u("Wast2Wasm"), scriptContext->GetThreadContext()->GetPageAllocator(), Throw::OutOfMemory);
    Context context;
    size_t wastSize;
    char* wastBuffer = nullptr;

    ENTER_PINNED_SCOPE(JavascriptString, string);
    string = (JavascriptString*)args[1];
    const char16* str = string->GetString();
    context.allocator = &arena;
    context.scriptContext = scriptContext;

    size_t origSize = string->GetLength();
    auto allocator = [&arena](size_t size) {return (utf8char_t*)AnewArray(&arena, byte, size);};
    utf8::WideStringToNarrow(allocator, str, origSize, &wastBuffer, &wastSize);
    LEAVE_PINNED_SCOPE();   //  string

    try
    {
        ChakraWabt::SpecContext spec;
        ChakraWabt::ChakraContext wabtCtx;
        wabtCtx.user_data = &context;
        wabtCtx.createBuffer = CreateBuffer;
        wabtCtx.features.sign_extends = CONFIG_FLAG(WasmSignExtends);
        if (isSpecText)
        {
            wabtCtx.spec = &spec;
            spec.setProperty = SetProperty;
            spec.int32ToVar = Int32ToVar;
            spec.int64ToVar = Int64ToVar;
            spec.stringToVar = StringToVar;
            spec.createObject = CreateObject;
            spec.createArray = CreateArray;
            spec.push = Push;
        }
        void* result = ChakraWabt::ConvertWast2Wasm(wabtCtx, wastBuffer, (uint)wastSize, isSpecText);
        if (result == nullptr)
        {
            return scriptContext->GetLibrary()->GetUndefined();
        }
        return result;
    }
    catch (ChakraWabt::Error& e)
    {
        JavascriptError::ThrowTypeErrorVar(scriptContext, WABTERR_WabtError, NarrowStringToWide(&context, e.message));
    }
}