Skip to content

Commit

Permalink
Merge branch 'master' into HostPromiseRejection
Browse files Browse the repository at this point in the history
  • Loading branch information
rhuanjl authored Jan 31, 2018
2 parents dcdaf1f + e9b9c49 commit 4769f67
Show file tree
Hide file tree
Showing 45 changed files with 3,203 additions and 8,596 deletions.
7 changes: 7 additions & 0 deletions lib/Backend/EmitBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ template <typename TAlloc, typename TPreReservedAlloc, class SyncObject>
void
EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::FreeAllocations(bool release)
{
#if PDATA_ENABLED && defined(_WIN32)
DelayDeletingFunctionTable::Clear();
#endif

AutoRealOrFakeCriticalSection<SyncObject> autoCs(&this->criticalSection);

#if DBG_DUMP
Expand Down Expand Up @@ -194,6 +197,10 @@ template <typename TAlloc, typename TPreReservedAlloc, class SyncObject>
bool
EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::FreeAllocation(void* address)
{
#if PDATA_ENABLED && defined(_WIN32)
DelayDeletingFunctionTable::Clear();
#endif

AutoRealOrFakeCriticalSection<SyncObject> autoCs(&this->criticalSection);

#if _M_ARM
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5195,6 +5195,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
break;

case Js::OpCode::Typeof:
case Js::OpCode::TypeofElem:
return this->NewGenericValue(ValueType::String, dst);
case Js::OpCode::InitLocalClosure:
Assert(instr->GetDst());
Expand Down
8 changes: 0 additions & 8 deletions lib/Backend/InterpreterThunkEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,6 @@ void* InterpreterThunkEmitter::ConvertToEntryPoint(PVOID dynamicInterpreterThunk

bool InterpreterThunkEmitter::NewThunkBlock()
{
// flush the function tables before allocating any new code
// to prevent old function table is referring to new code address
DelayDeletingFunctionTable::Clear();

#ifdef ENABLE_OOP_NATIVE_CODEGEN
if (CONFIG_FLAG(ForceStaticInterpreterThunk))
{
Expand Down Expand Up @@ -401,10 +397,6 @@ bool InterpreterThunkEmitter::NewThunkBlock()
#ifdef ENABLE_OOP_NATIVE_CODEGEN
bool InterpreterThunkEmitter::NewOOPJITThunkBlock()
{
// flush the function tables before allocating any new code
// to prevent old function table is referring to new code address
DelayDeletingFunctionTable::Clear();

PSCRIPTCONTEXT_HANDLE remoteScriptContext = this->scriptContext->GetRemoteScriptAddr();
if (!JITManager::GetJITManager()->IsConnected())
{
Expand Down
10 changes: 5 additions & 5 deletions lib/Backend/NativeCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ NativeCodeGenerator::~NativeCodeGenerator()
{
Assert(this->IsClosed());

#if PDATA_ENABLED && defined(_WIN32)
DelayDeletingFunctionTable::Clear();
#endif

#ifdef PROFILE_EXEC
if (this->foregroundCodeGenProfiler != nullptr)
Expand Down Expand Up @@ -902,10 +904,6 @@ void NativeCodeGenerator::CodeGen(PageAllocator* pageAllocator, CodeGenWorkItemI
void
NativeCodeGenerator::CodeGen(PageAllocator * pageAllocator, CodeGenWorkItem* workItem, const bool foreground)
{
// flush the function tables before allocating any new code
// to prevent old function table is referring to new code address
DelayDeletingFunctionTable::Clear();

if(foreground)
{
// Func::Codegen has a lot of things on the stack, so probe the stack here instead
Expand Down Expand Up @@ -1117,7 +1115,6 @@ NativeCodeGenerator::CodeGen(PageAllocator * pageAllocator, CodeGenWorkItem* wor
}

#if defined(TARGET_64)
DelayDeletingFunctionTable::Clear();
XDataAllocation * xdataInfo = HeapNewZ(XDataAllocation);
xdataInfo->address = (byte*)jitWriteData.xdataAddr;
XDataAllocator::Register(xdataInfo, jitWriteData.codeAddress, jitWriteData.codeSize);
Expand Down Expand Up @@ -3257,6 +3254,9 @@ NativeCodeGenerator::FreeNativeCodeGenAllocation(void* codeAddress)
{
if (JITManager::GetJITManager()->IsOOPJITEnabled())
{
#if PDATA_ENABLED && defined(_WIN32)
DelayDeletingFunctionTable::Clear();
#endif
ThreadContext * context = this->scriptContext->GetThreadContext();
HRESULT hr = JITManager::GetJITManager()->FreeAllocation(context->GetRemoteThreadContextAddr(), (intptr_t)codeAddress);
JITManager::HandleServerCallResult(hr, RemoteCallType::MemFree);
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/PDataManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_

// Since we do not expect many thunk functions to be created, we are using 1 table/function
// for now. This can be optimized further if needed.
DWORD status = NtdllLibrary::Instance->AddGrowableFunctionTable(pdataTable,
NTSTATUS status = NtdllLibrary::Instance->AddGrowableFunctionTable(pdataTable,
pdataStart,
entryCount,
maxEntryCount,
Expand Down
14 changes: 12 additions & 2 deletions lib/Common/Common/Jobs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,10 @@ namespace JsUtil
threadId(GetCurrentThreadContextId()),
threadService(threadService),
threadCount(0),
maxThreadCount(0),
hasExtraWork(false)
maxThreadCount(0)
#if PDATA_ENABLED && defined(_WIN32)
,hasExtraWork(false)
#endif
{
if (!threadService->HasCallback())
{
Expand Down Expand Up @@ -678,7 +680,9 @@ namespace JsUtil
//Wait for 1 sec on jobReady and shutdownBackgroundThread events.
unsigned int result = WaitForMultipleObjectsEx(_countof(handles), handles, false, 1000, false);

#if PDATA_ENABLED && defined(_WIN32)
DoExtraWork();
#endif

while (result == WAIT_TIMEOUT)
{
Expand Down Expand Up @@ -706,6 +710,7 @@ namespace JsUtil
return result == WAIT_OBJECT_0;
}

#if PDATA_ENABLED && defined(_WIN32)
void BackgroundJobProcessor::DoExtraWork()
{
while (hasExtraWork)
Expand All @@ -714,6 +719,7 @@ namespace JsUtil
Sleep(50);
}
}
#endif

bool BackgroundJobProcessor::WaitWithThreadForThreadStartedOrClosingEvent(ParallelThreadData *parallelThreadData, const unsigned int milliseconds)
{
Expand Down Expand Up @@ -1117,8 +1123,10 @@ namespace JsUtil
}
criticalSection.Leave();

#if PDATA_ENABLED && defined(_WIN32)
// flush the function tables in background thread after closed and before shutting down thread
DelayDeletingFunctionTable::Clear();
#endif

EDGE_ETW_INTERNAL(EventWriteJSCRIPT_NATIVECODEGEN_STOP(this, 0));
}
Expand Down Expand Up @@ -1420,6 +1428,7 @@ namespace JsUtil
#endif
}

#if PDATA_ENABLED && defined(_WIN32)
void BackgroundJobProcessor::StartExtraWork()
{
hasExtraWork = true;
Expand All @@ -1431,6 +1440,7 @@ namespace JsUtil
{
hasExtraWork = false;
}
#endif

#if DBG_DUMP
//Just for debugging purpose
Expand Down
8 changes: 8 additions & 0 deletions lib/Common/Common/Jobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,10 @@ namespace JsUtil
// Closes the job processor and closes the handle of background threads.
virtual void Close();

#if PDATA_ENABLED && defined(_WIN32)
virtual void StartExtraWork() { };
virtual void EndExtraWork() { };
#endif
};

// -------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -460,7 +462,9 @@ namespace JsUtil
unsigned int maxThreadCount;
ParallelThreadData **parallelThreadData;

#if PDATA_ENABLED && defined(_WIN32)
bool hasExtraWork;
#endif

#if DBG_DUMP
static char16 const * const DebugThreadNames[16];
Expand All @@ -470,8 +474,10 @@ namespace JsUtil
BackgroundJobProcessor(AllocationPolicyManager* policyManager, ThreadService *threadService, bool disableParallelThreads);
~BackgroundJobProcessor();

#if PDATA_ENABLED && defined(_WIN32)
virtual void StartExtraWork() override;
virtual void EndExtraWork() override;
#endif

private:
bool WaitWithThread(ParallelThreadData *parallelThreadData, const Event &e, const unsigned int milliseconds = INFINITE);
Expand All @@ -489,7 +495,9 @@ namespace JsUtil
void InitializeParallelThreadData(AllocationPolicyManager* policyManager, bool disableParallelThreads);
void InitializeParallelThreadDataForThreadServiceCallBack(AllocationPolicyManager* policyManager);

#if PDATA_ENABLED && defined(_WIN32)
void DoExtraWork();
#endif

public:
virtual void AddManager(JobManager *const manager) override;
Expand Down
3 changes: 1 addition & 2 deletions lib/Common/Core/ConfigParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,7 @@ HRESULT ConfigParser::SetOutputFile(const WCHAR* outputFile, const WCHAR* openMo
_wcsicmp(fileName, _u("ByteCodeGenerator")) == 0 ||
_wcsicmp(fileName, _u("spartan")) == 0 ||
_wcsicmp(fileName, _u("spartan_edge")) == 0 ||
_wcsicmp(fileName, _u("MicrosoftEdge")) == 0 ||
_wcsicmp(fileName, _u("MicrosoftEdgeCP")) == 0)
_wcsnicmp(fileName, _u("MicrosoftEdge"), wcslen(_u("MicrosoftEdge"))) == 0)
{

// we need to output to %temp% directory in wwa. we don't have permission otherwise.
Expand Down
11 changes: 6 additions & 5 deletions lib/Common/Core/DelayLoadLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ LPCTSTR NtdllLibrary::GetLibraryName() const
#if PDATA_ENABLED

_Success_(return == 0)
DWORD NtdllLibrary::AddGrowableFunctionTable( _Out_ PVOID * DynamicTable,
NtdllLibrary::NTSTATUS NtdllLibrary::AddGrowableFunctionTable( _Out_ PVOID * DynamicTable,
_In_reads_(MaximumEntryCount) PRUNTIME_FUNCTION FunctionTable,
_In_ DWORD EntryCount,
_In_ DWORD MaximumEntryCount,
Expand All @@ -82,16 +82,17 @@ DWORD NtdllLibrary::AddGrowableFunctionTable( _Out_ PVOID * DynamicTable,
return 1;
}
}
DWORD status = addGrowableFunctionTable(DynamicTable,
NTSTATUS status = addGrowableFunctionTable(DynamicTable,
FunctionTable,
EntryCount,
MaximumEntryCount,
RangeBase,
RangeEnd);
#if _M_X64
PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("Register: Begin: %llx, End: %x, Unwind: %llx, RangeBase: %llx, RangeEnd: %llx, table: %llx, Status: %x\n"),
FunctionTable->BeginAddress, FunctionTable->EndAddress, FunctionTable->UnwindInfoAddress, RangeBase, RangeEnd, *DynamicTable, status);
PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("Register: [%d] Begin: %llx, End: %x, Unwind: %llx, RangeBase: %llx, RangeEnd: %llx, table: %llx, Status: %x\n"),
GetCurrentThreadId(), FunctionTable->BeginAddress, FunctionTable->EndAddress, FunctionTable->UnwindInfoAddress, RangeBase, RangeEnd, *DynamicTable, status);
#endif
Assert((status >= 0 && FunctionTable != nullptr) || status == 0xC000009A /*STATUS_INSUFFICIENT_RESOURCES*/);
return status;
}
return 1;
Expand All @@ -113,7 +114,7 @@ VOID NtdllLibrary::DeleteGrowableFunctionTable( _In_ PVOID DynamicTable )
}
deleteGrowableFunctionTable(DynamicTable);

PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("UnRegister: table: %llx\n"), DynamicTable);
PHASE_PRINT_TESTTRACE1(Js::XDataPhase, _u("UnRegister: [%d] table: %llx\n"), GetCurrentThreadId(), DynamicTable);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Common/Core/DelayLoadLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class NtdllLibrary : protected DelayLoadLibrary

#if PDATA_ENABLED
_Success_(return == 0)
DWORD AddGrowableFunctionTable(_Out_ PVOID * DynamicTable,
NTSTATUS AddGrowableFunctionTable(_Out_ PVOID * DynamicTable,
_In_reads_(MaximumEntryCount) PRUNTIME_FUNCTION FunctionTable,
_In_ DWORD EntryCount,
_In_ DWORD MaximumEntryCount,
Expand Down
19 changes: 3 additions & 16 deletions lib/Common/Memory/DelayDeletingFunctionTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@
#if PDATA_ENABLED && defined(_WIN32)
#include "Core/DelayLoadLibrary.h"
#include <malloc.h>
#endif

PSLIST_HEADER DelayDeletingFunctionTable::Head = nullptr;
DelayDeletingFunctionTable DelayDeletingFunctionTable::Instance;

DelayDeletingFunctionTable::DelayDeletingFunctionTable()
{
#if PDATA_ENABLED && defined(_WIN32)
Head = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
if (Head)
{
InitializeSListHead(Head);
}
#endif
}
DelayDeletingFunctionTable::~DelayDeletingFunctionTable()
{
#if PDATA_ENABLED && defined(_WIN32)
Clear();
if (Head)
{
Expand All @@ -34,13 +30,11 @@ DelayDeletingFunctionTable::~DelayDeletingFunctionTable()
_aligned_free(Head);
Head = nullptr;
}
#endif
}


bool DelayDeletingFunctionTable::AddEntry(FunctionTableHandle ft)
{
#if PDATA_ENABLED && defined(_WIN32)
if (Head)
{
FunctionTableNode* node = (FunctionTableNode*)_aligned_malloc(sizeof(FunctionTableNode), MEMORY_ALLOCATION_ALIGNMENT);
Expand All @@ -51,13 +45,11 @@ bool DelayDeletingFunctionTable::AddEntry(FunctionTableHandle ft)
return true;
}
}
#endif
return false;
}

void DelayDeletingFunctionTable::Clear()
{
#if PDATA_ENABLED && defined(_WIN32)
if (Head)
{
SLIST_ENTRY* entry = InterlockedPopEntrySList(Head);
Expand All @@ -69,21 +61,16 @@ void DelayDeletingFunctionTable::Clear()
entry = InterlockedPopEntrySList(Head);
}
}
#endif
}

bool DelayDeletingFunctionTable::IsEmpty()
{
#if PDATA_ENABLED && defined(_WIN32)
return QueryDepthSList(Head) == 0;
#else
return true;
#endif
}

void DelayDeletingFunctionTable::DeleteFunctionTable(void* functionTable)
{
#if PDATA_ENABLED && defined(_WIN32)
NtdllLibrary::Instance->DeleteGrowableFunctionTable(functionTable);
#endif
}
}

#endif
7 changes: 3 additions & 4 deletions lib/Common/Memory/XDataAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
#include "Memory/arm64/XDataAllocator.h"
#endif

#if PDATA_ENABLED && defined(_WIN32)
struct FunctionTableNode
{
#ifdef _WIN32
SLIST_ENTRY itemEntry;
FunctionTableHandle functionTable;

#endif
};

struct DelayDeletingFunctionTable
Expand All @@ -33,4 +31,5 @@ struct DelayDeletingFunctionTable
static void Clear();
static bool IsEmpty();
static void DeleteFunctionTable(void* functionTable);
};
};
#endif
10 changes: 8 additions & 2 deletions lib/Common/Memory/amd64/XDataAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,20 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionSta
BOOLEAN success = FALSE;
if (AutoSystemInfo::Data.IsWin8OrLater())
{
DWORD status = NtdllLibrary::Instance->AddGrowableFunctionTable(&xdataInfo->functionTable,
#if DBG
// Validate the PDATA was not registered or unregistered
ULONG64 imageBase = 0;
RUNTIME_FUNCTION *runtimeFunction = RtlLookupFunctionEntry((DWORD64)functionStart, &imageBase, nullptr);
Assert(runtimeFunction == NULL);
#endif

NTSTATUS status = NtdllLibrary::Instance->AddGrowableFunctionTable(&xdataInfo->functionTable,
&xdataInfo->pdata,
/*MaxEntryCount*/ 1,
/*Valid entry count*/ 1,
/*RangeBase*/ functionStart,
/*RangeEnd*/ functionStart + functionSize);
success = NT_SUCCESS(status);
Assert(success && xdataInfo->functionTable != nullptr);
}
else
{
Expand Down
Loading

0 comments on commit 4769f67

Please sign in to comment.