//
// Get URL from source context, called by LogMethodNativeLoadEvent and LogLoopBodyLoadEvent
//
utf8char_t* VTuneChakraProfile::GetUrl(Js::FunctionBody* body, size_t* urlBufferLength )
{
    utf8char_t* utf8Url = NULL;
    if (!body->GetSourceContextInfo()->IsDynamic())
    {
        const wchar* url = body->GetSourceContextInfo()->url;
        if (url)
        {
            size_t urlCharLength = wcslen(url);
            urlCharLength = min(urlCharLength, (size_t)UINT_MAX);       // Just truncate if it is too big

            *urlBufferLength = urlCharLength * 3 + 1;
            utf8Url = HeapNewNoThrowArray(utf8char_t, *urlBufferLength);
            if (utf8Url)
            {
                utf8::EncodeIntoAndNullTerminate(utf8Url, url, (charcount_t)urlCharLength);
            }
        }
    }
    else
    {
        utf8Url = (utf8char_t*)VTuneChakraProfile::DynamicCode;
    }
    return utf8Url;
}
Esempio n. 2
0
    BYTE* WebAssemblySharedArrayBuffer::AllocBuffer(uint32 length, uint32 maxLength)
    {
#if ENABLE_FAST_ARRAYBUFFER
        if (CONFIG_FLAG(WasmFastArray))
        {
            return (BYTE*)WasmVirtualAllocator(length);
        }
#endif
#ifdef _WIN32
        if (CONFIG_FLAG(WasmSharedArrayVirtualBuffer))
        {
            return (BYTE*)AllocWrapper(length, maxLength);
        }
#endif
        AssertOrFailFast(maxLength >= length);
        uint32 additionalSize = maxLength - length;
        if (additionalSize > 0)
        {
            // SharedArrayBuffer::Init already requested External Memory for `length`, we need to request the balance
            if (!this->GetRecycler()->RequestExternalMemoryAllocation(additionalSize))
            {
                // Failed to request for more memory
                return nullptr;
            }
        }
        // Allocate the full size of the buffer if we can't do VirtualAlloc
        return HeapNewNoThrowArray(BYTE, maxLength);
    }
Esempio n. 3
0
    BYTE* SharedArrayBuffer::AllocBuffer(uint32 length, uint32 maxLength)
    {
        Unused(maxLength); // WebAssembly only
#if ENABLE_FAST_ARRAYBUFFER
        if (this->IsValidVirtualBufferLength(length))
        {
            return (BYTE*)AsmJsVirtualAllocator(length);
        }
        else
#endif
        {
            return HeapNewNoThrowArray(BYTE, length);
        }
    }
Esempio n. 4
0
void JsrtDebugUtils::AddSouceToObject(Js::DynamicObject * object, Js::Utf8SourceInfo * utf8SourceInfo)
{
    int32 cchLength = utf8SourceInfo->GetCchLength();
    AutoArrayPtr<char16> sourceContent(HeapNewNoThrowArray(char16, cchLength + 1), cchLength + 1);
    if (sourceContent != nullptr)
    {
        utf8::DecodeOptions options = utf8SourceInfo->IsCesu8() ? utf8::doAllowThreeByteSurrogates : utf8::doDefault;
        utf8::DecodeIntoAndNullTerminate(sourceContent, utf8SourceInfo->GetSource(), cchLength, options);
        JsrtDebugUtils::AddPropertyToObject(object, JsrtDebugPropertyId::source, sourceContent, cchLength, utf8SourceInfo->GetScriptContext());
    }
    else
    {
        JsrtDebugUtils::AddPropertyToObject(object, JsrtDebugPropertyId::source, _u(""), 1, utf8SourceInfo->GetScriptContext());
    }
}
//
// Log loop body load event to VTune 
//
void VTuneChakraProfile::LogLoopBodyLoadEvent(Js::FunctionBody* body, Js::LoopHeader* loopHeader, Js::LoopEntryPointInfo* entryPoint, uint16 loopNumber)
{
#if ENABLE_NATIVE_CODEGEN
    if (isJitProfilingActive)
    {
        iJIT_Method_Load methodInfo;
        memset(&methodInfo, 0, sizeof(iJIT_Method_Load));
        const char16* methodName = body->GetExternalDisplayName();
        size_t methodLength = wcslen(methodName);
        methodLength = min(methodLength, (size_t)UINT_MAX); // Just truncate if it is too big
        size_t length = methodLength * 3 + /* spaces */ 2 + _countof(LoopStr) + /*size of loop number*/ 10 + /*NULL*/ 1;
        utf8char_t* utf8MethodName = HeapNewNoThrowArray(utf8char_t, length);
        if(utf8MethodName)
        {
            methodInfo.method_id = iJIT_GetNewMethodID();
            size_t len = utf8::EncodeInto(utf8MethodName, methodName, (charcount_t)methodLength);
            sprintf_s((char*)(utf8MethodName + len), length - len," %s %d", LoopStr, loopNumber + 1);
            methodInfo.method_name = (char*)utf8MethodName;
            methodInfo.method_load_address = (void*)entryPoint->GetNativeAddress();
            methodInfo.method_size = (uint)entryPoint->GetCodeSize();        // Size in memory - Must be exact

            size_t urlLength  = 0;
            utf8char_t* utf8Url = GetUrl(body, &urlLength);
            methodInfo.source_file_name = (char*)utf8Url;

            iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &methodInfo);
            OUTPUT_TRACE(Js::ProfilerPhase, _u("Loop body load event: %s Loop %d\n"), methodName, loopNumber + 1);

            if(urlLength > 0)
            {
                HeapDeleteArray(urlLength, utf8Url);
            }
            HeapDeleteArray(length, utf8MethodName);
        }
    }
#endif
}
Esempio n. 6
0
void JsrtDebugUtils::AddSourceLengthAndTextToObject(Js::DynamicObject* object, Js::FunctionBody* functionBody, int byteCodeOffset)
{
    Js::FunctionBody::StatementMap* statementMap = functionBody->GetEnclosingStatementMapFromByteCode(byteCodeOffset);
    Assert(statementMap != nullptr);

    LPCUTF8 source = functionBody->GetStartOfDocument(_u("Source for debugging"));
    size_t startByte = utf8::CharacterIndexToByteIndex(source, functionBody->GetUtf8SourceInfo()->GetCbLength(), (const charcount_t)statementMap->sourceSpan.begin);

    int byteLength = statementMap->sourceSpan.end - statementMap->sourceSpan.begin;

    JsrtDebugUtils::AddPropertyToObject(object, JsrtDebugPropertyId::sourceLength, (double)byteLength, functionBody->GetScriptContext());

    AutoArrayPtr<char16> sourceContent(HeapNewNoThrowArray(char16, byteLength + 1), byteLength + 1);
    if (sourceContent != nullptr)
    {
        utf8::DecodeOptions options = functionBody->GetUtf8SourceInfo()->IsCesu8() ? utf8::doAllowThreeByteSurrogates : utf8::doDefault;
        utf8::DecodeIntoAndNullTerminate(sourceContent, source + startByte, byteLength, options);
        JsrtDebugUtils::AddPropertyToObject(object, JsrtDebugPropertyId::sourceText, sourceContent, byteLength, functionBody->GetScriptContext());
    }
    else
    {
        JsrtDebugUtils::AddPropertyToObject(object, JsrtDebugPropertyId::sourceText, _u(""), 1, functionBody->GetScriptContext());
    }
}
//
// Log JIT method native load event to VTune 
//
void VTuneChakraProfile::LogMethodNativeLoadEvent(Js::FunctionBody* body, Js::FunctionEntryPointInfo* entryPoint)
{
#if ENABLE_NATIVE_CODEGEN
    if (isJitProfilingActive)
    {
        iJIT_Method_Load methodInfo;
        memset(&methodInfo, 0, sizeof(iJIT_Method_Load));
        const char16* methodName = body->GetExternalDisplayName();
        // Append function line number info to method name so that VTune can distinguish between polymorphic methods
        char16 methodNameBuffer[_MAX_PATH];
        ULONG lineNumber = body->GetLineNumber();
        char16 numberBuffer[20];
        _ltow_s(lineNumber, numberBuffer, 10);
        wcscpy_s(methodNameBuffer, methodName);
        if (entryPoint->GetJitMode() == ExecutionMode::SimpleJit)
        {
            wcscat_s(methodNameBuffer, _u(" Simple"));
        }
        wcscat_s(methodNameBuffer, _u(" {line:"));
        wcscat_s(methodNameBuffer, numberBuffer);
        wcscat_s(methodNameBuffer, _u("}"));

        size_t methodLength = wcslen(methodNameBuffer);
        Assert(methodLength < _MAX_PATH);
        size_t length = methodLength * 3 + 1;
        utf8char_t* utf8MethodName = HeapNewNoThrowArray(utf8char_t, length);
        if (utf8MethodName)
        {
            methodInfo.method_id = iJIT_GetNewMethodID();
            utf8::EncodeIntoAndNullTerminate(utf8MethodName, methodNameBuffer, (charcount_t)methodLength);
            methodInfo.method_name = (char*)utf8MethodName;
            methodInfo.method_load_address = (void*)entryPoint->GetNativeAddress();
            methodInfo.method_size = (uint)entryPoint->GetCodeSize();        // Size in memory - Must be exact

            LineNumberInfo numberInfo[1];

            uint lineCount = (entryPoint->GetNativeOffsetMapCount()) * 2 + 1; // may need to record both .begin and .end for all elements
            LineNumberInfo* pLineInfo = HeapNewNoThrowArray(LineNumberInfo, lineCount);

            if (pLineInfo == NULL || Js::Configuration::Global.flags.DisableVTuneSourceLineInfo)
            {
                // resort to original implementation, attribute all samples to first line
                numberInfo[0].LineNumber = lineNumber;
                numberInfo[0].Offset = 0;
                methodInfo.line_number_size = 1;
                methodInfo.line_number_table = numberInfo;
            }
            else
            {
                int size = entryPoint->PopulateLineInfo(pLineInfo, body);
                methodInfo.line_number_size = size;
                methodInfo.line_number_table = pLineInfo;
            }

            size_t urlLength = 0;
            utf8char_t* utf8Url = GetUrl(body, &urlLength);
            methodInfo.source_file_name = (char*)utf8Url;
            OUTPUT_TRACE(Js::ProfilerPhase, _u("Method load event: %s\n"), methodNameBuffer);
            iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &methodInfo);

            HeapDeleteArray(lineCount, pLineInfo);

            if (urlLength > 0)
            {
                HeapDeleteArray(urlLength, utf8Url);
            }

            HeapDeleteArray(length, utf8MethodName);
        }
    }
#endif
}