Exemplo n.º 1
0
HRESULT
ServerFreeAllocation(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t threadContextInfo,
    /* [in] */ intptr_t address)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
    ServerThreadContext * context = (ServerThreadContext*)DecodePointer((void*)threadContextInfo);

    if (context == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsThreadContextAlive(context))
    {
        Assert(false);
        return E_ACCESSDENIED;
    }

    return ServerCallWrapper(context, [&]()->HRESULT 
    {
        AutoReleaseContext<ServerThreadContext> autoThreadContext(context);
        context->SetValidCallTargetForCFG((PVOID)address, false);
        context->GetCodeGenAllocators()->emitBufferManager.FreeAllocation((void*)address);
        return S_OK;
    });
}
Exemplo n.º 2
0
HRESULT
ServerAddModuleRecordInfo(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t scriptContextInfoAddress,
    /* [in] */ unsigned int moduleId,
    /* [in] */ intptr_t localExportSlotsAddr)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerScriptContext * serverScriptContext = (ServerScriptContext*)DecodePointer((void*)scriptContextInfoAddress);
    if (serverScriptContext == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsScriptContextAlive(serverScriptContext))
    {
        Assert(false);
        return E_ACCESSDENIED;
    }

    AutoReleaseContext<ServerScriptContext> autoScriptContext(serverScriptContext);
    return ServerCallWrapper(serverScriptContext, [&]()->HRESULT
    {
        serverScriptContext->AddModuleRecordInfo(moduleId, localExportSlotsAddr);
        return S_OK;
    });

}
Exemplo n.º 3
0
HRESULT
ServerAddDOMFastPathHelper(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t scriptContextRoot,
    /* [in] */ intptr_t funcInfoAddr,
    /* [in] */ int helper)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer((void*)scriptContextRoot);

    if (scriptContextInfo == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsScriptContextAlive(scriptContextInfo))
    {
        Assert(false);
        return E_ACCESSDENIED;
    }

    AutoReleaseContext<ServerScriptContext> autoScriptContext(scriptContextInfo);
    return ServerCallWrapper(scriptContextInfo, [&]()->HRESULT
    {
        scriptContextInfo->AddToDOMFastPathHelperMap(funcInfoAddr, (IR::JnHelperMethod)helper);
        return S_OK;
    });
}
Exemplo n.º 4
0
HRESULT
ServerInitializeThreadContext(
    /* [in] */ handle_t binding,
    /* [in] */ __RPC__in ThreadContextDataIDL * threadContextData,
    /* [out] */ __RPC__out intptr_t *threadContextRoot,
    /* [out] */ __RPC__out intptr_t *prereservedRegionAddr)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerThreadContext * contextInfo = HeapNewNoThrow(ServerThreadContext, threadContextData);
    if (contextInfo == nullptr)
    {
        return E_OUTOFMEMORY;
    }

    AutoReleaseContext<ServerThreadContext> autoThreadContext(contextInfo);
    return ServerCallWrapper(contextInfo, [&]()->HRESULT
    {
        ServerContextManager::RegisterThreadContext(contextInfo);

        *threadContextRoot = (intptr_t)EncodePointer(contextInfo);
        *prereservedRegionAddr = (intptr_t)contextInfo->GetPreReservedVirtualAllocator()->EnsurePreReservedRegion();

        return S_OK;
    });
}
Exemplo n.º 5
0
HRESULT
ServerInitializeScriptContext(
    /* [in] */ handle_t binding,
    /* [in] */ __RPC__in ScriptContextDataIDL * scriptContextData,
    /* [in] */ intptr_t threadContextInfoAddress,
    /* [out] */ __RPC__out intptr_t * scriptContextInfoAddress)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer((void*)threadContextInfoAddress);

    if (threadContextInfo == nullptr)
    {
        Assert(false);
        *scriptContextInfoAddress = 0;
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsThreadContextAlive(threadContextInfo))
    {
        Assert(false);
        *scriptContextInfoAddress = 0;
        return E_ACCESSDENIED;
    }

    return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
    {
        ServerScriptContext * contextInfo = HeapNew(ServerScriptContext, scriptContextData, threadContextInfo);

        ServerContextManager::RegisterScriptContext(contextInfo);

        *scriptContextInfoAddress = (intptr_t)EncodePointer(contextInfo);

#if !FLOATVAR
        // TODO: should move this to ServerInitializeThreadContext, also for the fields in IDL
        XProcNumberPageSegmentImpl::Initialize(contextInfo->IsRecyclerVerifyEnabled(), contextInfo->GetRecyclerVerifyPad());
#endif
        return S_OK;
    });
}
Exemplo n.º 6
0
ArenaMemoryData *
MemoryProfiler::Begin(LPCWSTR name)
{
    if (!Js::Configuration::Global.flags.IsEnabled(Js::TraceMemoryFlag))
    {
        return nullptr;
    }
    Assert(name != nullptr);
    if (wcscmp(name, _u("MemoryProfiler")) == 0)
    {
        // Don't profile memory profiler itself
        return nullptr;
    }

    // This is debug only code, we don't care if we catch the right exception
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_DisableCheck);
    MemoryProfiler * memoryProfiler = EnsureMemoryProfiler();
    ArenaMemoryDataSummary * arenaTotalMemoryData;
    if (!memoryProfiler->arenaDataMap.TryGetValue((LPWSTR)name, &arenaTotalMemoryData))
    {
        arenaTotalMemoryData = AnewStructZ(&memoryProfiler->alloc, ArenaMemoryDataSummary);
        memoryProfiler->arenaDataMap.Add((LPWSTR)name, arenaTotalMemoryData);
    }
    arenaTotalMemoryData->arenaCount++;

    ArenaMemoryData * memoryData = AnewStructZ(&memoryProfiler->alloc, ArenaMemoryData);
    if (arenaTotalMemoryData->data == nullptr)
    {
        arenaTotalMemoryData->data = memoryData;
    }
    else
    {
        memoryData->next = arenaTotalMemoryData->data;
        arenaTotalMemoryData->data->prev = memoryData;
        arenaTotalMemoryData->data = memoryData;
    }
    memoryData->profiler = memoryProfiler;
    return memoryData;
}
Exemplo n.º 7
0
HRESULT
ServerCleanupThreadContext(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t threadContextRoot)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer((void*)threadContextRoot);
    if (threadContextInfo == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (ServerContextManager::IsThreadContextAlive(threadContextInfo))
    {
        AutoReleaseContext<ServerThreadContext> autoThreadContext(threadContextInfo);
        threadContextInfo->Close();
        ServerContextManager::UnRegisterThreadContext(threadContextInfo);
    }
    return S_OK;
}
Exemplo n.º 8
0
HRESULT
ServerUpdatePropertyRecordMap(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t threadContextInfoAddress,
    /* [in] */ __RPC__in UpdatedPropertysIDL * updatedProps)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));

    ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer((void*)threadContextInfoAddress);

    if (threadContextInfo == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsThreadContextAlive(threadContextInfo))
    {
        Assert(false);
        return E_ACCESSDENIED;
    }

    AutoReleaseContext<ServerThreadContext> autoThreadContext(threadContextInfo);
    return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
    {
        for (uint i = 0; i < updatedProps->reclaimedPropertyCount; ++i)
        {
            threadContextInfo->RemoveFromPropertyMap((Js::PropertyId)updatedProps->reclaimedPropertyIdArray[i]);
        }

        for (uint i = 0; i < updatedProps->newRecordCount; ++i)
        {
            threadContextInfo->AddToPropertyMap((Js::PropertyRecord *)updatedProps->newRecordArray[i]);
        }

        return S_OK;
    });
}
Exemplo n.º 9
0
HRESULT
ServerRemoteCodeGen(
    /* [in] */ handle_t binding,
    /* [in] */ intptr_t scriptContextInfoAddress,
    /* [in] */ __RPC__in CodeGenWorkItemIDL *workItemData,
    /* [out] */ __RPC__out JITOutputIDL *jitData)
{
    AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
    LARGE_INTEGER start_time = { 0 };
    if (PHASE_TRACE1(Js::BackEndPhase))
    {
        QueryPerformanceCounter(&start_time);
    }
    memset(jitData, 0, sizeof(JITOutputIDL));

    ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer((void*)scriptContextInfoAddress);

    if (scriptContextInfo == nullptr)
    {
        Assert(false);
        return RPC_S_INVALID_ARG;
    }

    if (!ServerContextManager::IsScriptContextAlive(scriptContextInfo))
    {
        Assert(false);
        return E_ACCESSDENIED;
    }

    AutoReleaseContext<ServerScriptContext> autoScriptContext(scriptContextInfo);

    return ServerCallWrapper(scriptContextInfo, [&]() ->HRESULT
    {
        scriptContextInfo->UpdateGlobalObjectThisAddr(workItemData->globalThisAddr);
        ServerThreadContext * threadContextInfo = scriptContextInfo->GetThreadContext();

        NoRecoverMemoryJitArenaAllocator jitArena(L"JITArena", threadContextInfo->GetPageAllocator(), Js::Throw::OutOfMemory);
        JITTimeWorkItem * jitWorkItem = Anew(&jitArena, JITTimeWorkItem, workItemData);

        if (PHASE_VERBOSE_TRACE_RAW(Js::BackEndPhase, jitWorkItem->GetJITTimeInfo()->GetSourceContextId(), jitWorkItem->GetJITTimeInfo()->GetLocalFunctionId()))
        {
            LARGE_INTEGER freq;
            LARGE_INTEGER end_time;
            QueryPerformanceCounter(&end_time);
            QueryPerformanceFrequency(&freq);

            Output::Print(
                L"BackendMarshalIn - function: %s time:%8.6f mSec\r\n",
                jitWorkItem->GetJITFunctionBody()->GetDisplayName(),
                (((double)((end_time.QuadPart - workItemData->startTime)* (double)1000.0 / (double)freq.QuadPart))) / (1));
            Output::Flush();
        }

        auto profiler = scriptContextInfo->GetCodeGenProfiler();
#ifdef PROFILE_EXEC
        if (profiler && !profiler->IsInitialized())
        {
            profiler->Initialize(threadContextInfo->GetPageAllocator(), nullptr);
        }
#endif
        if (jitWorkItem->GetWorkItemData()->xProcNumberPageSegment)
        {
            jitData->numberPageSegments = (XProcNumberPageSegment*)midl_user_allocate(sizeof(XProcNumberPageSegment));
            if (!jitData->numberPageSegments)
            {
                return E_OUTOFMEMORY;
            }
            __analysis_assume(jitData->numberPageSegments);

            memcpy_s(jitData->numberPageSegments, sizeof(XProcNumberPageSegment), jitWorkItem->GetWorkItemData()->xProcNumberPageSegment, sizeof(XProcNumberPageSegment));
        }

        Func::Codegen(
            &jitArena,
            jitWorkItem,
            threadContextInfo,
            scriptContextInfo,
            jitData,
            nullptr,
            nullptr,
            jitWorkItem->GetPolymorphicInlineCacheInfo(),
            threadContextInfo->GetCodeGenAllocators(),
#if !FLOATVAR
            nullptr, // number allocator
#endif
            profiler,
            true);


#ifdef PROFILE_EXEC
        if (profiler && profiler->IsInitialized())
        {
            profiler->ProfilePrint(Js::Configuration::Global.flags.Profile.GetFirstPhase());
        }
#endif

        if (PHASE_VERBOSE_TRACE_RAW(Js::BackEndPhase, jitWorkItem->GetJITTimeInfo()->GetSourceContextId(), jitWorkItem->GetJITTimeInfo()->GetLocalFunctionId()))
        {
            LARGE_INTEGER freq;
            LARGE_INTEGER end_time;
            QueryPerformanceCounter(&end_time);
            QueryPerformanceFrequency(&freq);

            Output::Print(
                L"EndBackEndInner - function: %s time:%8.6f mSec\r\n",
                jitWorkItem->GetJITFunctionBody()->GetDisplayName(),
                (((double)((end_time.QuadPart - start_time.QuadPart)* (double)1000.0 / (double)freq.QuadPart))) / (1));
            Output::Flush();

        }
        LARGE_INTEGER out_time = { 0 };
        if (PHASE_TRACE1(Js::BackEndPhase))
        {
            QueryPerformanceCounter(&out_time);
            jitData->startTime = out_time.QuadPart;
        }

        return S_OK;
    });
}
void ThreadBoundThreadContextManager::DestroyAllContexts()
{
#if ENABLE_BACKGROUND_JOB_PROCESSOR
    JsUtil::BackgroundJobProcessor * jobProcessor = NULL;
#endif
    
    {
        AutoCriticalSection lock(ThreadContext::GetCriticalSection());

        ThreadContextTLSEntry * currentEntry = ThreadContextTLSEntry::GetEntryForCurrentThread();

        if (currentEntry == NULL)
        {
            // We need a current thread entry so that we can use it to release any thread contexts
            // we find below.
            try
            {
                AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_OutOfMemory);
                currentEntry = ThreadContextTLSEntry::CreateEntryForCurrentThread();
                entries.Prepend(currentEntry);
            }
            catch (Js::OutOfMemoryException)
            {
                return;
            }
        }
        else
        {
            // We need to clear out the current thread entry so that we can use it to release any
            // thread contexts we find below.
            ThreadContext * threadContext = static_cast<ThreadContext *>(currentEntry->GetThreadContext());

            if (threadContext != NULL)
            {
                if (threadContext->IsThreadBound())
                {
                    ShutdownThreadContext(threadContext);
                    ThreadContextTLSEntry::ClearThreadContext(currentEntry, false);
                }
                else
                {
                    ThreadContextTLSEntry::ClearThreadContext(currentEntry, true);
                }
            }
        }

        EntryList::Iterator iter(&entries);

        while (iter.Next())
        {
            ThreadContextTLSEntry * entry = iter.Data();
            ThreadContext * threadContext =  static_cast<ThreadContext *>(entry->GetThreadContext());

            if (threadContext != nullptr)
            {
                // Found a thread context. Remove it from the containing entry.
                ThreadContextTLSEntry::ClearThreadContext(entry, true);
                // Now set it to our thread's entry.
                ThreadContextTLSEntry::SetThreadContext(currentEntry, threadContext);
                // Clear it out.
                ShutdownThreadContext(threadContext);
                // Now clear it out of our entry.
                ThreadContextTLSEntry::ClearThreadContext(currentEntry, false);
            }
        }

        // We can only clean up our own TLS entry, so we're going to go ahead and do that here.
        entries.Remove(currentEntry);
        ThreadContextTLSEntry::CleanupThread();

#if ENABLE_BACKGROUND_JOB_PROCESSOR
        if (s_sharedJobProcessor != NULL)
        {
            jobProcessor = s_sharedJobProcessor;
            s_sharedJobProcessor = NULL;

            jobProcessor->Close();
        }
#endif
    }

#if ENABLE_BACKGROUND_JOB_PROCESSOR
    if (jobProcessor != NULL)
    {
        HeapDelete(jobProcessor);
    }
#endif
}