SourceDynamicProfileManager *
    SourceDynamicProfileManager::Deserialize(T * reader, Recycler* recycler)
    {
        uint functionCount;
        if (!reader->Peek(&functionCount))
        {
            return nullptr;
        }

        BVFixed * startupFunctions = BVFixed::New(functionCount, recycler);
        if (!reader->ReadArray(((char *)startupFunctions),
            BVFixed::GetAllocSize(functionCount)))
        {
            return nullptr;
        }

        uint profileCount;

        if (!reader->Read(&profileCount))
        {
            return nullptr;
        }

        ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread();

        SourceDynamicProfileManager * sourceDynamicProfileManager = RecyclerNew(threadContext->GetRecycler(), SourceDynamicProfileManager, recycler);

        sourceDynamicProfileManager->cachedStartupFunctions = startupFunctions;

#if DBG_DUMP
        if(Configuration::Global.flags.Dump.IsEnabled(DynamicProfilePhase))
        {
            Output::Print(L"Loaded: Startup functions bit vector:");
            startupFunctions->Dump();
        }
#endif

        for (uint i = 0; i < profileCount; i++)
        {
            Js::LocalFunctionId functionId;
            DynamicProfileInfo * dynamicProfileInfo = DynamicProfileInfo::Deserialize(reader, recycler, &functionId);
            if (dynamicProfileInfo == nullptr || functionId >= functionCount)
            {
                return nullptr;
            }
            sourceDynamicProfileManager->dynamicProfileInfoMap.Add(functionId, dynamicProfileInfo);
        }
        return sourceDynamicProfileManager;
    }
예제 #2
0
 // Recover/Release unused memory and give it back to OS.
 // The function doesn't throw if the attempt to recover memory fails, in which case it simply does nothing.
 // Useful when running out of memory e.g. for Arena but there is some recycler memory which has been committed but is unused.
 void Exception::RecoverUnusedMemory()
 {
     ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread();
     if (threadContext)
     {
         Recycler* threadRecycler = threadContext->GetRecycler();
         if (threadRecycler)
         {
             try
             {
                 threadRecycler->CollectNow<CollectOnRecoverFromOutOfMemory>();
             }
             catch (...)
             {
                 // Technically, exception is a valid scenario: we asked to recover mem, and it couldn't.
                 // Do not let the exception leak out.
             }
         }
     }
 }
예제 #3
0
    void Utf8SourceInfo::EnsureInitialized(int initialFunctionCount)
    {
        ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread();
        Recycler* recycler = threadContext->GetRecycler();

        if (this->functionBodyDictionary == nullptr)
        {
            // This collection is allocated with leaf allocation policy. The references to the function body
            // here does not keep the function alive. However, the functions remove themselves at finalize
            // so if a function actually is in this map, it means that it is alive.
            this->functionBodyDictionary = RecyclerNew(recycler, FunctionBodyDictionary, recycler,
                initialFunctionCount, threadContext->GetEtwRundownCriticalSection());
        }

        if (CONFIG_FLAG(DeferTopLevelTillFirstCall) && !m_deferredFunctionsInitialized)
        {
            Assert(this->m_deferredFunctionsDictionary == nullptr);
            this->m_deferredFunctionsDictionary = RecyclerNew(recycler, DeferredFunctionsDictionary, recycler,
                initialFunctionCount, threadContext->GetEtwRundownCriticalSection());
            m_deferredFunctionsInitialized = true;
        }
    }
예제 #4
0
/* static */
bool JsrtContext::TrySetCurrent(JsrtContext * context)
{
    Assert(s_tlsSlot != TLS_OUT_OF_INDEXES);

    ThreadContext * threadContext;

    //We are not pinning the context after SetCurrentContext, so if the context is not pinned
    //it might be reclaimed half way during execution. In jsrtshell the runtime was optimized out
    //at time of JsrtContext::Run by the compiler.
    //The change is to pin the context at setconcurrentcontext, and unpin the previous one. In
    //JsDisposeRuntime we'll reject if current context is active, so that will make sure all
    //contexts are unpinned at time of JsDisposeRuntime.
    if (context != nullptr)
    {
        threadContext = context->GetScriptContext()->GetThreadContext();

        if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
        {
            return false;
        }
        threadContext->GetRecycler()->RootAddRef((LPVOID)context);
    }
    else
    {
        if (!ThreadContextTLSEntry::ClearThreadContext(true))
        {
            return false;
        }
    }

    JsrtContext* originalContext = (JsrtContext*) TlsGetValue(s_tlsSlot);
    if (originalContext != nullptr)
    {
        originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
    }

    TlsSetValue(s_tlsSlot, context);
    return true;
}
예제 #5
0
Js::ScriptContext* JsrtContextCore::EnsureScriptContext()
{
    Assert(this->GetJavascriptLibrary() == nullptr);

    ThreadContext* localThreadContext = this->GetRuntime()->GetThreadContext();

    AutoPtr<Js::ScriptContext> newScriptContext(Js::ScriptContext::New(localThreadContext));

    newScriptContext->Initialize();

    hostContext = HeapNew(ChakraCoreHostScriptContext, newScriptContext);
    newScriptContext->SetHostScriptContext(hostContext);

    this->SetJavascriptLibrary(newScriptContext.Detach()->GetLibrary());

    Js::JavascriptLibrary *library = this->GetScriptContext()->GetLibrary();
    Assert(library != nullptr);
    localThreadContext->GetRecycler()->RootRelease(library->GetGlobalObject());

    library->GetEvalFunctionObject()->SetEntryPoint(&Js::GlobalObject::EntryEval);
    library->GetFunctionConstructor()->SetEntryPoint(&Js::JavascriptFunction::NewInstance);

    return this->GetScriptContext();
}