diff --git a/.gitignore b/.gitignore index cdfb4e498cb..08cd53d07c0 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ install_manifest.txt *.o Makefile pal/src/config.h +DbgController.js.h # Generated by other tools *.orig diff --git a/bin/ChakraCore/ChakraCoreShared.cpp b/bin/ChakraCore/ChakraCoreShared.cpp index 78a477458ab..c5ea785d97a 100644 --- a/bin/ChakraCore/ChakraCoreShared.cpp +++ b/bin/ChakraCore/ChakraCoreShared.cpp @@ -15,6 +15,7 @@ void DummyJSRTCall() JsRuntimeHandle *runtime; JsRuntimeAttributes attr; JsCreateRuntime(attr, nullptr, runtime); + JsDiagStartDebugging(runtime, nullptr, nullptr); } #endif @@ -30,4 +31,4 @@ EXTERN_C BOOL WINAPI DllMain(HINSTANCE hmod, DWORD dwReason, PVOID pvReserved) return TRUE; } -static_assert(__LINE__ == 33, "You shouldn't add anything to this file or ChakraCoreDllFunc.cpp. Please consider again!"); +static_assert(__LINE__ == 34, "You shouldn't add anything to this file or ChakraCoreDllFunc.cpp. Please consider again!"); diff --git a/bin/ch/Debugger.h b/bin/ch/Debugger.h index b91d2a7b43a..f56472ddb3a 100644 --- a/bin/ch/Debugger.h +++ b/bin/ch/Debugger.h @@ -10,9 +10,9 @@ static const char controllerScript[] = { '\0' }; #else -static const char controllerScript[] = { '\0' }; +#include "DbgController.js.h" #endif - + class Debugger { public: diff --git a/bin/ch/jstoc.py b/bin/ch/jstoc.py new file mode 100755 index 00000000000..bc4c2c974bb --- /dev/null +++ b/bin/ch/jstoc.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +#------------------------------------------------------------------------------------------------------- +# Copyright (C) Microsoft. All rights reserved. +# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +#------------------------------------------------------------------------------------------------------- + +from __future__ import with_statement # py 2.5 +import sys +import os + +def print_usage(): + print "jstoc tool" + print "creates a (const char array) from a javascript file." + print "" + print "usage: jstoc.py " + sys.exit(1) + +def convert(): + if len(sys.argv) < 3: + print_usage() + + js_file_name = sys.argv[1] + if os.path.isfile(js_file_name) == False: + print_usage() + + h_file_name = js_file_name + '.h' + + js_file_time = os.path.getmtime(js_file_name) + h_file_time = 0 + if os.path.isfile(h_file_name): + h_file_time = os.path.getmtime(h_file_name) + + str_header = "static const char " + sys.argv[2] + "[] = {\n" + + # if header file is up to date and no update to jstoc.py since, skip.. + if h_file_time < js_file_time or h_file_time < os.path.getmtime(sys.argv[0]): + with open(js_file_name, "rb") as js_file: + last_break = len(str_header) # skip first line + byte = js_file.read(1) + while byte: + str_header += str(ord(byte)) + str_header += "," + # beautify a bit. limit column to ~80 + column_check = (len(str_header) + 1) - last_break + if column_check > 5 and column_check % 80 < 5: + last_break = len(str_header) + 1 + str_header += "\n" + else: + str_header += " " + byte = js_file.read(1) + str_header += "0\n};" + + h_file = open(h_file_name, "w") + h_file.write(str_header) + h_file.close() + print "-- " + h_file_name + " is created" + else: + print "-- " + h_file_name + " is up to date. skipping." + +if __name__ == '__main__': + sys.exit(convert()) +else: + print("try without python") diff --git a/build.sh b/build.sh index 9e9d508a34b..7ff93b223d7 100755 --- a/build.sh +++ b/build.sh @@ -338,6 +338,13 @@ if [[ ${#_CXX} > 0 ]]; then CC_PREFIX="-DCMAKE_CXX_COMPILER=$_CXX -DCMAKE_C_COMPILER=$_CC" fi +# prepare DbgController.js.h +CH_DIR="${CHAKRACORE_DIR}/bin/ch" +"${CH_DIR}/jstoc.py" "${CH_DIR}/DbgController.js" controllerScript +if [[ $? != 0 ]]; then + exit 1 +fi + build_directory="$CHAKRACORE_DIR/BuildLinux/${BUILD_TYPE:0}" if [ ! -d "$build_directory" ]; then SAFE_RUN `mkdir -p $build_directory` diff --git a/lib/Backend/NativeCodeGenerator.cpp b/lib/Backend/NativeCodeGenerator.cpp index 8f079da4133..b14758b296e 100644 --- a/lib/Backend/NativeCodeGenerator.cpp +++ b/lib/Backend/NativeCodeGenerator.cpp @@ -940,7 +940,7 @@ NativeCodeGenerator::CodeGen(PageAllocator * pageAllocator, CodeGenWorkItem* wor Func::Codegen(&jitArena, jitWorkItem, scriptContext->GetThreadContext(), scriptContext, &jitWriteData, epInfo, nullptr, jitWorkItem->GetPolymorphicInlineCacheInfo(), allocators, #if !FLOATVAR - pNumberAllocator, + pNumberAllocator, #endif codeGenProfiler, !foreground); } @@ -1548,7 +1548,7 @@ NativeCodeGenerator::CheckCodeGen(Js::ScriptFunction * function) if(!nativeCodeGen->Processor()->PrioritizeJob(nativeCodeGen, entryPoint, function)) { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) #define originalEntryPoint_IS_ProfileDeferredParsingThunk \ (originalEntryPoint == ProfileDeferredParsingThunk) #else @@ -2005,7 +2005,7 @@ NativeCodeGenerator::JobProcessed(JsUtil::Job *const job, const bool succeeded) Assert(workItem->GetCodeAddress() != NULL); uint loopNum = loopBodyCodeGen->GetJITData()->loopNumber; - functionBody->SetLoopBodyEntryPoint(loopBodyCodeGen->loopHeader, entryPoint, (Js::JavascriptMethod)workItem->GetCodeAddress(), loopNum); + functionBody->SetLoopBodyEntryPoint(loopBodyCodeGen->loopHeader, entryPoint, (Js::JavascriptMethod)workItem->GetCodeAddress(), loopNum); entryPoint->SetCodeGenDone(); } else diff --git a/lib/Common/BackendApi.h b/lib/Common/BackendApi.h index 8a3b4f31104..7ed0c955ce1 100644 --- a/lib/Common/BackendApi.h +++ b/lib/Common/BackendApi.h @@ -19,7 +19,7 @@ #define ProfileEntryThunk Js::ScriptContext::DebugProfileProbeThunk #define DefaultDeferredParsingThunk Js::JavascriptFunction::DeferredParsingThunk -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) #define ProfileDeferredParsingThunk Js::ScriptContext::ProfileModeDeferredParsingThunk #endif diff --git a/lib/Common/CommonDefines.h b/lib/Common/CommonDefines.h index 71cc21471f9..52f0d9115a5 100644 --- a/lib/Common/CommonDefines.h +++ b/lib/Common/CommonDefines.h @@ -113,8 +113,6 @@ #ifdef _WIN32 // dep: TIME_ZONE_INFORMATION, DaylightTimeHelper, Windows.Globalization #define ENABLE_GLOBALIZATION -// dep: IDebugDocumentContext -#define ENABLE_SCRIPT_DEBUGGING // dep: IActiveScriptProfilerCallback, IActiveScriptProfilerHeapEnum #define ENABLE_SCRIPT_PROFILING #ifndef __clang__ @@ -125,6 +123,9 @@ #define ENABLE_CUSTOM_ENTROPY #endif +// dep: IDebugDocumentContext +#define ENABLE_SCRIPT_DEBUGGING + // GC features // Concurrent and Partial GC are disabled on non-Windows builds @@ -351,7 +352,7 @@ #if ENABLE_TTD #define TTDAssert(C, M) { if(!(C)) TTDAbort_fatal_error(M); } #else -#define TTDAssert(C, M) +#define TTDAssert(C, M) #endif #if ENABLE_TTD diff --git a/lib/Common/CommonPal.h b/lib/Common/CommonPal.h index 6256c1f0c19..c967990348e 100644 --- a/lib/Common/CommonPal.h +++ b/lib/Common/CommonPal.h @@ -628,6 +628,16 @@ void TryFinally(const TryFunc& tryFunc, const FinallyFunc& finallyFunc) finallyFunc(hasException); } +#ifdef DISABLE_SEH +#define __TRY_FINALLY_BEGIN TryFinally([&]() +#define __FINALLY , [&](bool /* hasException */) +#define __TRY_FINALLY_END ); +#else +#define __TRY_FINALLY_BEGIN __try +#define __FINALLY __finally +#define __TRY_FINALLY_END +#endif + namespace PlatformAgnostic { __forceinline unsigned char _BitTestAndSet(LONG *_BitBase, int _BitPos) @@ -690,3 +700,4 @@ namespace PlatformAgnostic #include "PlatformAgnostic/SystemInfo.h" #include "PlatformAgnostic/Thread.h" #include "PlatformAgnostic/AssemblyCommon.h" +#include "PlatformAgnostic/Debugger.h" diff --git a/lib/Common/Memory/amd64/XDataAllocator.cpp b/lib/Common/Memory/amd64/XDataAllocator.cpp index 9eabd3b12ff..490d39ef694 100644 --- a/lib/Common/Memory/amd64/XDataAllocator.cpp +++ b/lib/Common/Memory/amd64/XDataAllocator.cpp @@ -34,6 +34,7 @@ bool XDataAllocator::Initialize(void* segmentStart, void* segmentEnd) XDataAllocator::~XDataAllocator() { + current = nullptr; ClearFreeList(); } @@ -42,7 +43,8 @@ void XDataAllocator::Delete() HeapDelete(this); } -bool XDataAllocator::Alloc(ULONG_PTR functionStart, DWORD functionSize, ushort pdataCount, ushort xdataSize, SecondaryAllocation* allocation) +bool XDataAllocator::Alloc(ULONG_PTR functionStart, DWORD functionSize, + ushort pdataCount, ushort xdataSize, SecondaryAllocation* allocation) { XDataAllocation* xdata = static_cast(allocation); Assert(start != nullptr); @@ -107,6 +109,7 @@ void XDataAllocator::ClearFreeList() { entry = next; next = entry->next; + entry->address = nullptr; HeapDelete(entry); } this->freeList = NULL; diff --git a/lib/Common/PlatformAgnostic/Debugger.h b/lib/Common/PlatformAgnostic/Debugger.h new file mode 100644 index 00000000000..3a076fbbfa6 --- /dev/null +++ b/lib/Common/PlatformAgnostic/Debugger.h @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +#ifndef RUNTIME_PLATFORM_AGNOSTIC_DEBUGGER +#define RUNTIME_PLATFORM_AGNOSTIC_DEBUGGER + +#ifndef _WIN32 + +#define ACTIVPROF_E_PROFILER_PRESENT 0x0200 +#define ACTIVPROF_E_PROFILER_ABSENT 0x0201 +#define ACTIVPROF_E_UNABLE_TO_APPLY_ACTION 0x0202 +#define PROFILER_TOKEN uint + +typedef enum { + PROFILER_SCRIPT_TYPE_USER, + PROFILER_SCRIPT_TYPE_DYNAMIC, + PROFILER_SCRIPT_TYPE_NATIVE, + PROFILER_SCRIPT_TYPE_DOM +} PROFILER_SCRIPT_TYPE; + +typedef enum { + PROFILER_EVENT_MASK_TRACE_SCRIPT_FUNCTION_CALL = 0x00000001, + PROFILER_EVENT_MASK_TRACE_NATIVE_FUNCTION_CALL = 0x00000002, + PROFILER_EVENT_MASK_TRACE_DOM_FUNCTION_CALL = 0x00000004, + PROFILER_EVENT_MASK_TRACE_ALL = + PROFILER_EVENT_MASK_TRACE_SCRIPT_FUNCTION_CALL | + PROFILER_EVENT_MASK_TRACE_NATIVE_FUNCTION_CALL, + PROFILER_EVENT_MASK_TRACE_ALL_WITH_DOM = PROFILER_EVENT_MASK_TRACE_ALL | + PROFILER_EVENT_MASK_TRACE_DOM_FUNCTION_CALL +} PROFILER_EVENT_MASK; + +interface IEnumDebugCodeContexts : IUnknown +{ + // HRESULT Next( .. + + // HRESULT Skip( .. + + // HRESULT Reset(); + + // HRESULT Clone( .. +}; + +interface IDebugDocumentInfo : IUnknown +{ + HRESULT GetName(char* dn, BSTR *name); + + HRESULT GetDocumentClassId(CLSID *dclsid); +}; + +interface IDebugDocument : IDebugDocumentInfo +{ +}; + +interface IDebugDocumentContext : IUnknown +{ + HRESULT GetDocument(IDebugDocument **doc); + + HRESULT EnumCodeContexts(IEnumDebugCodeContexts **dctx); +}; + +class IActiveScriptProfilerCallback +{ +public: + HRESULT Initialize(DWORD ctx) + { + return S_OK; + } + + HRESULT Shutdown(HRESULT _) + { + return S_OK; + } + + HRESULT Release() + { + return S_OK; + } + + HRESULT QueryInterface(IActiveScriptProfilerCallback **_) + { + return S_OK; + } + + HRESULT ScriptCompiled(PROFILER_TOKEN scriptId, PROFILER_SCRIPT_TYPE type, IUnknown *ctx) + { + return S_OK; + } + + HRESULT FunctionCompiled(PROFILER_TOKEN functionId, PROFILER_TOKEN scriptId, + const WCHAR* pwszFunctionName, const WCHAR* pwszFunctionNameHint, IUnknown *ctx) + { + return S_OK; + } + + HRESULT OnFunctionEnter(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId) + { + return S_OK; + } + + HRESULT OnFunctionExit(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId) + { + return S_OK; + } + + // IActiveScriptProfilerCallback2 + HRESULT OnFunctionEnterByName(const WCHAR *functionName, PROFILER_SCRIPT_TYPE _) + { + return S_OK; + } + + HRESULT OnFunctionExitByName(const WCHAR *functionName, PROFILER_SCRIPT_TYPE _) + { + return S_OK; + } + + // IActiveScriptProfilerCallback3 + HRESULT AddRef() + { + return S_OK; + } + + HRESULT SetWebWorkerId(PROFILER_TOKEN _) + { + return S_OK; + } +}; + +#define IActiveScriptProfilerCallback2 IActiveScriptProfilerCallback +#define IActiveScriptProfilerCallback3 IActiveScriptProfilerCallback + +#endif // !_WIN32 + +#endif // RUNTIME_PLATFORM_AGNOSTIC_DEBUGGER diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp index 8b422a15d39..951a7fa0549 100644 --- a/lib/Jsrt/Jsrt.cpp +++ b/lib/Jsrt/Jsrt.cpp @@ -3454,9 +3454,9 @@ CHAKRA_API JsTTDStart() Js::ScriptContext* scriptContext = currentContext->GetScriptContext(); TTDAssert(scriptContext->IsTTDRecordOrReplayModeEnabled(), "Need to create in TTD Record Mode."); - +#if ENABLE_NATIVE_CODEGEN TTDAssert(JITManager::GetJITManager() == nullptr || !JITManager::GetJITManager()->IsOOPJITEnabled(), "TTD cannot run with OOP JIT yet!!!"); - +#endif return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { if(scriptContext->IsTTDRecordModeEnabled()) diff --git a/lib/Runtime/Base/CrossSite.cpp b/lib/Runtime/Base/CrossSite.cpp index 139db9bc212..a015353aa2a 100644 --- a/lib/Runtime/Base/CrossSite.cpp +++ b/lib/Runtime/Base/CrossSite.cpp @@ -289,14 +289,14 @@ namespace Js bool CrossSite::IsThunk(JavascriptMethod thunk) { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) return (thunk == CrossSite::ProfileThunk || thunk == CrossSite::DefaultThunk); #else return (thunk == CrossSite::DefaultThunk); #endif } -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Var CrossSite::ProfileThunk(RecyclableObject* callable, CallInfo callInfo, ...) { JavascriptFunction* function = JavascriptFunction::FromVar(callable); diff --git a/lib/Runtime/Base/FunctionBody.cpp b/lib/Runtime/Base/FunctionBody.cpp index b67d0388dc9..00a62c384f5 100644 --- a/lib/Runtime/Base/FunctionBody.cpp +++ b/lib/Runtime/Base/FunctionBody.cpp @@ -883,11 +883,11 @@ namespace Js } #endif - PHASE_PRINT_TRACE(Js::RedeferralPhase, this, _u("Redeferring function %d.%d: %s\n"), + PHASE_PRINT_TRACE(Js::RedeferralPhase, this, _u("Redeferring function %d.%d: %s\n"), GetSourceContextId(), GetLocalFunctionId(), GetDisplayName() ? GetDisplayName() : _u("Anonymous function)")); - ParseableFunctionInfo * parseableFunctionInfo = + ParseableFunctionInfo * parseableFunctionInfo = Js::ParseableFunctionInfo::NewDeferredFunctionFromFunctionBody(this); FunctionInfo * functionInfo = this->GetFunctionInfo(); @@ -1423,7 +1423,7 @@ namespace Js CopyDeferParseField(m_cbLength); this->CopyNestedArray(other); -#undef CopyDeferParseField +#undef CopyDeferParseField } void ParseableFunctionInfo::Copy(FunctionBody* other) @@ -1608,7 +1608,7 @@ namespace Js ParseableFunctionInfo* ParseableFunctionInfo::New(ScriptContext* scriptContext, int nestedCount, LocalFunctionId functionId, Utf8SourceInfo* sourceInfo, const char16* displayName, uint displayNameLength, uint displayShortNameOffset, Js::PropertyRecordList* propertyRecords, FunctionInfo::Attributes attributes, FunctionBodyFlags flags) { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Assert( scriptContext->DeferredParsingThunk == ProfileDeferredParsingThunk || scriptContext->DeferredParsingThunk == DefaultDeferredParsingThunk); @@ -1646,7 +1646,7 @@ namespace Js flags); } - ParseableFunctionInfo * + ParseableFunctionInfo * ParseableFunctionInfo::NewDeferredFunctionFromFunctionBody(FunctionBody * functionBody) { ScriptContext * scriptContext = functionBody->GetScriptContext(); @@ -3455,7 +3455,7 @@ namespace Js #endif ; } -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) bool FunctionProxy::HasValidProfileEntryPoint() const { JavascriptMethod directEntryPoint = this->GetDefaultEntryPointInfo()->jsMethod; @@ -3500,7 +3500,7 @@ namespace Js { return this->HasValidNonProfileEntryPoint(); } -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) if (m_scriptContext->IsProfiling()) { return this->HasValidProfileEntryPoint(); @@ -3515,7 +3515,7 @@ namespace Js #endif void ParseableFunctionInfo::SetDeferredParsingEntryPoint() { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Assert(m_scriptContext->DeferredParsingThunk == ProfileDeferredParsingThunk || m_scriptContext->DeferredParsingThunk == DefaultDeferredParsingThunk); #else @@ -3528,13 +3528,13 @@ namespace Js void ParseableFunctionInfo::SetInitialDefaultEntryPoint() { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Assert(m_scriptContext->CurrentThunk == ProfileEntryThunk || m_scriptContext->CurrentThunk == DefaultEntryThunk); - Assert(this->GetOriginalEntryPoint_Unchecked() == DefaultDeferredParsingThunk || + Assert(this->GetOriginalEntryPoint_Unchecked() == DefaultDeferredParsingThunk || this->GetOriginalEntryPoint_Unchecked() == ProfileDeferredParsingThunk || - this->GetOriginalEntryPoint_Unchecked() == DefaultDeferredDeserializeThunk || + this->GetOriginalEntryPoint_Unchecked() == DefaultDeferredDeserializeThunk || this->GetOriginalEntryPoint_Unchecked() == ProfileDeferredDeserializeThunk || - this->GetOriginalEntryPoint_Unchecked() == DefaultEntryThunk || + this->GetOriginalEntryPoint_Unchecked() == DefaultEntryThunk || this->GetOriginalEntryPoint_Unchecked() == ProfileEntryThunk); #else Assert(m_scriptContext->CurrentThunk == DefaultEntryThunk); @@ -4951,12 +4951,12 @@ namespace Js { ProxyEntryPointInfo* defaultEntryPointInfo = this->GetDefaultEntryPointInfo(); if (defaultEntryPointInfo->jsMethod != DefaultDeferredParsingThunk -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) && defaultEntryPointInfo->jsMethod != ProfileDeferredParsingThunk #endif ) { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) // Just change the thunk, the cleanup will be done once the function gets called. if (this->m_scriptContext->CurrentThunk == ProfileEntryThunk) { diff --git a/lib/Runtime/Base/FunctionBody.h b/lib/Runtime/Base/FunctionBody.h index 5aa68298474..24453c36a87 100644 --- a/lib/Runtime/Base/FunctionBody.h +++ b/lib/Runtime/Base/FunctionBody.h @@ -574,7 +574,7 @@ namespace Js protected: #if PDATA_ENABLED XDataAllocation * xdataInfo; -#endif +#endif #endif // ENABLE_NATIVE_CODEGEN CodeGenWorkItem * workItem; @@ -1464,7 +1464,7 @@ namespace Js #if DBG bool HasValidEntryPoint() const; -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) bool HasValidProfileEntryPoint() const; #endif bool HasValidNonProfileEntryPoint() const; @@ -1579,7 +1579,7 @@ namespace Js Assert(GetFunctionInfo()->GetFunctionProxy() == this); return GetFunctionInfo()->IsAsync(); } - + inline bool FunctionProxy::IsDeferred() const { Assert(GetFunctionInfo()); @@ -1732,7 +1732,7 @@ namespace Js Assert(!IsDeferredDeserializeFunction()); return (ParseableFunctionInfo*)this; } - + inline DeferDeserializeFunctionInfo* FunctionProxy::GetDeferDeserializeFunctionInfo() const { Assert(IsDeferredDeserializeFunction()); @@ -3050,16 +3050,16 @@ namespace Js uint GetForInLoopDepth() const { return this->GetCountField(CounterFields::ForInLoopDepth); } uint SetForInLoopDepth(uint count) { return this->SetCountField(CounterFields::ForInLoopDepth, count); } - bool AllocProfiledForInLoopCount(ProfileId* profileId) + bool AllocProfiledForInLoopCount(ProfileId* profileId) { - ProfileId profiledForInLoopCount = this->GetProfiledForInLoopCount(); - if (profiledForInLoopCount != Constants::NoProfileId) - { - *profileId = profiledForInLoopCount; - this->IncreaseCountField(CounterFields::ProfiledForInLoopCount); - return true; - } - return false; + ProfileId profiledForInLoopCount = this->GetProfiledForInLoopCount(); + if (profiledForInLoopCount != Constants::NoProfileId) + { + *profileId = profiledForInLoopCount; + this->IncreaseCountField(CounterFields::ProfiledForInLoopCount); + return true; + } + return false; } ProfileId GetProfiledForInLoopCount() const { return (ProfileId)this->GetCountField(CounterFields::ProfiledForInLoopCount); } void SetProfiledForInLoopCount(ProfileId count) { this->SetCountField(CounterFields::ProfiledForInLoopCount, count); } @@ -3339,7 +3339,7 @@ namespace Js ForInCache * GetForInCacheArray(); void CleanUpForInCache(bool isShutdown); - void AllocateInlineCache(); + void AllocateInlineCache(); InlineCache * GetInlineCache(uint index); bool CanFunctionObjectHaveInlineCaches(); void** GetInlineCaches(); @@ -3350,8 +3350,8 @@ namespace Js IsInstInlineCache * GetIsInstInlineCache(uint index); PolymorphicInlineCache * GetPolymorphicInlineCache(uint index); PolymorphicInlineCache * CreateNewPolymorphicInlineCache(uint index, PropertyId propertyId, InlineCache * inlineCache); - PolymorphicInlineCache * CreateBiggerPolymorphicInlineCache(uint index, PropertyId propertyId); - private: + PolymorphicInlineCache * CreateBiggerPolymorphicInlineCache(uint index, PropertyId propertyId); + private: void ResetInlineCaches(); PolymorphicInlineCache * CreatePolymorphicInlineCache(uint index, uint16 size); diff --git a/lib/Runtime/Base/ScriptContext.cpp b/lib/Runtime/Base/ScriptContext.cpp index 2f9e2ea321d..24490e798c8 100644 --- a/lib/Runtime/Base/ScriptContext.cpp +++ b/lib/Runtime/Base/ScriptContext.cpp @@ -3071,6 +3071,34 @@ namespace Js } HRESULT hr = S_OK; + +#ifndef _WIN32 + BEGIN_TRANSLATE_OOM_TO_HRESULT_NESTED + { + // xplat eh_frame handling is a bit different than Windows + // RecreateNativeCodeGenerator call below will be cleaning up + // XDataAllocation and we won't be able to __DEREGISTER_FRAME + + // xplat-todo: make eh_frame handling better + this->sourceList->Map([=](uint i, RecyclerWeakReference* sourceInfoWeakRef) { + Js::Utf8SourceInfo* sourceInfo = sourceInfoWeakRef->Get(); + + if (sourceInfo != nullptr) + { + sourceInfo->MapFunction([](Js::FunctionBody* functionBody) { + functionBody->ResetEntryPoint(); + }); + } + }); + } + END_TRANSLATE_OOM_TO_HRESULT(hr); + + if (FAILED(hr)) + { + return hr; + } +#endif + if (!CONFIG_FLAG(ForceDiagnosticsMode)) { #if ENABLE_NATIVE_CODEGEN @@ -3113,12 +3141,14 @@ namespace Js functionBody->SetEntryToDeferParseForDebugger(); }); } +#ifdef _WIN32 else { sourceInfo->MapFunction([](Js::FunctionBody* functionBody) { functionBody->ResetEntryPoint(); }); } +#endif } }); } @@ -3134,7 +3164,6 @@ namespace Js this->RegisterDebugThunk(); } - #if ENABLE_PROFILE_INFO #if DBG_DUMP || defined(DYNAMIC_PROFILE_STORAGE) || defined(RUNTIME_DATA_COLLECTION) // Reset the dynamic profile list @@ -3147,12 +3176,12 @@ namespace Js return hr; } +#if defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING) // We use ProfileThunk under debugger. void ScriptContext::RegisterDebugThunk(bool calledDuringAttach /*= true*/) { if (this->IsExceptionWrapperForBuiltInsEnabled()) { -#ifdef ENABLE_SCRIPT_PROFILING this->CurrentThunk = ProfileEntryThunk; this->CurrentCrossSiteThunk = CrossSite::ProfileThunk; #if ENABLE_NATIVE_CODEGEN @@ -3163,16 +3192,14 @@ namespace Js // are created with entry point set to the ProfileThunk. this->javascriptLibrary->SetProfileMode(true); this->javascriptLibrary->SetDispatchProfile(true, DispatchProfileInvoke); + +#ifdef ENABLE_SCRIPT_PROFILING if (!calledDuringAttach) { -#ifdef ENABLE_SCRIPT_PROFILING m_fTraceDomCall = TRUE; // This flag is always needed in DebugMode to wrap external functions with DebugProfileThunk -#endif // Update the function objects currently present in there. this->SetFunctionInRecyclerToProfileMode(true/*enumerateNonUserFunctionsOnly*/); } -#else - AssertMsg(false, "Profiling needs to be enabled to call RegisterDebugThunk"); #endif } } @@ -3194,6 +3221,7 @@ namespace Js } } } +#endif // defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING) #ifdef ENABLE_SCRIPT_PROFILING HRESULT ScriptContext::RegisterBuiltinFunctions(RegisterExternalLibraryType RegisterExternalLibrary) @@ -3389,7 +3417,7 @@ namespace Js scriptFunction->ChangeEntryPoint(pBody->GetDefaultFunctionEntryPointInfo(), newEntryPoint); } -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) void ScriptContext::RecyclerEnumClassEnumeratorCallback(void *address, size_t size) { // TODO: we are assuming its function because for now we are enumerating only on functions @@ -3430,6 +3458,7 @@ namespace Js char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE]; #endif +#if defined(ENABLE_SCRIPT_PROFILING) OUTPUT_TRACE(Js::ScriptProfilerPhase, _u("ScriptContext::RecyclerEnumClassEnumeratorCallback\n")); OUTPUT_TRACE(Js::ScriptProfilerPhase, _u("\tFunctionProxy : 0x%08X, FunctionNumber : %s, DeferredParseAttributes : %d, EntryPoint : 0x%08X"), (DWORD_PTR)proxy, proxy->GetDebugNumberSet(debugStringBuffer), proxy->GetAttributes(), (DWORD_PTR)entryPoint); @@ -3438,6 +3467,7 @@ namespace Js IsTrueOrFalse(IsIntermediateCodeGenThunk(entryPoint)), IsTrueOrFalse(scriptContext->IsNativeAddress(entryPoint))); #endif OUTPUT_TRACE(Js::ScriptProfilerPhase, _u("\n")); +#endif #if ENABLE_NATIVE_CODEGEN if (!IsIntermediateCodeGenThunk(entryPoint) && entryPoint != DynamicProfileInfo::EnsureDynamicProfileInfoThunk) @@ -3448,7 +3478,7 @@ namespace Js ScriptFunction * scriptFunction = ScriptFunction::FromVar(pFunction); scriptFunction->ChangeEntryPoint(proxy->GetDefaultEntryPointInfo(), Js::ScriptContext::GetProfileModeThunk(entryPoint)); -#if ENABLE_NATIVE_CODEGEN +#if ENABLE_NATIVE_CODEGEN && defined(ENABLE_SCRIPT_PROFILING) OUTPUT_TRACE(Js::ScriptProfilerPhase, _u("\tUpdated entrypoint : 0x%08X (isNative : %s)\n"), (DWORD_PTR)pFunction->GetEntryPoint(), IsTrueOrFalse(scriptContext->IsNativeAddress(entryPoint))); #endif } @@ -3489,9 +3519,9 @@ namespace Js JavascriptMethod ScriptContext::GetProfileModeThunk(JavascriptMethod entryPoint) { -#if ENABLE_NATIVE_CODEGEN + #if ENABLE_NATIVE_CODEGEN Assert(!IsIntermediateCodeGenThunk(entryPoint)); -#endif + #endif if (entryPoint == DefaultDeferredParsingThunk || entryPoint == ProfileDeferredParsingThunk) { return ProfileDeferredParsingThunk; @@ -3508,7 +3538,7 @@ namespace Js } return ProfileEntryThunk; } -#endif // ENABLE_SCRIPT_PROFILING +#endif // defined(ENABLE_SCRIPT_PROFILING) || defiend(ENABLE_SCRIPT_DEBUGGING) #if _M_IX86 __declspec(naked) @@ -3717,12 +3747,7 @@ namespace Js Assert(!AsmJsScriptFunction::IsWasmScriptFunction(callable)); JavascriptFunction* function = JavascriptFunction::FromVar(callable); ScriptContext* scriptContext = function->GetScriptContext(); - PROFILER_TOKEN scriptId = -1; - PROFILER_TOKEN functionId = -1; bool functionEnterEventSent = false; - - const bool isProfilingUserCode = scriptContext->GetThreadContext()->IsProfilingUserCode(); - const bool isUserCode = !function->IsLibraryCode(); char16 *pwszExtractedFunctionName = NULL; const char16 *pwszFunctionName = NULL; HRESULT hrOfEnterEvent = S_OK; @@ -3730,6 +3755,12 @@ namespace Js // We can come here when profiling is not on // e.g. User starts profiling, we update all thinks and then stop profiling - we don't update thunk // So we still get this call +#if defined(ENABLE_SCRIPT_PROFILING) + PROFILER_TOKEN scriptId = -1; + PROFILER_TOKEN functionId = -1; + const bool isProfilingUserCode = scriptContext->GetThreadContext()->IsProfilingUserCode(); + const bool isUserCode = !function->IsLibraryCode(); + const bool fProfile = (isUserCode || isProfilingUserCode) // Only report user code or entry library code && scriptContext->GetProfileInfo(function, scriptId, functionId); @@ -3754,7 +3785,7 @@ namespace Js } AssertMsg(pBody == NULL || pBody->GetProfileSession() == pBody->GetScriptContext()->GetProfileSession(), "Function info wasn't reported for this profile session"); } -#endif +#endif // DEBUG if (functionId == -1) { @@ -3803,11 +3834,12 @@ namespace Js scriptContext->GetThreadContext()->SetIsProfilingUserCode(isUserCode); // Update IsProfilingUserCode state } +#endif // ENABLE_SCRIPT_PROFILING Var aReturn = NULL; JavascriptMethod origEntryPoint = function->GetFunctionInfo()->GetOriginalEntryPoint(); - __try + __TRY_FINALLY_BEGIN // SEH is not guaranteed, see the implementation { Assert(!function->IsScriptFunction() || function->GetFunctionProxy()); @@ -3848,14 +3880,15 @@ namespace Js { threadContext->GetDebugManager()->GetDebuggingFlags()->SetIsBuiltInWrapperPresent(false); } - __try + __TRY_FINALLY_BEGIN // SEH is not guaranteed, see the implementation { aReturn = JavascriptFunction::CallFunction(function, origEntryPoint, args); } - __finally + __FINALLY { threadContext->GetDebugManager()->GetDebuggingFlags()->SetIsBuiltInWrapperPresent(isOrigWrapperPresent); } + __TRY_FINALLY_END } else { @@ -3866,8 +3899,9 @@ namespace Js } } } - __finally + __FINALLY { +#if defined(ENABLE_SCRIPT_PROFILING) if (fProfile) { if (hrOfEnterEvent != ACTIVPROF_E_PROFILER_ABSENT) @@ -3892,12 +3926,14 @@ namespace Js scriptContext->GetThreadContext()->SetIsProfilingUserCode(isProfilingUserCode); // Restore IsProfilingUserCode state } +#endif if (scriptContext->IsScriptContextInDebugMode()) { scriptContext->GetDebugContext()->GetProbeContainer()->EndRecordingCall(aReturn, function); } } + __TRY_FINALLY_END return aReturn; #else @@ -3905,7 +3941,7 @@ namespace Js #endif // defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING) } -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING) // Part of ProfileModeThunk which is called in debug mode (debug or debug & profile). Var ScriptContext::ProfileModeThunk_DebugModeWrapper(JavascriptFunction* function, ScriptContext* scriptContext, JavascriptMethod entryPoint, Arguments& args) { @@ -3917,7 +3953,9 @@ namespace Js return aReturn; } +#endif +#ifdef ENABLE_SCRIPT_PROFILING HRESULT ScriptContext::OnScriptCompiled(PROFILER_TOKEN scriptId, PROFILER_SCRIPT_TYPE type, IUnknown *pIDebugDocumentContext) { // TODO : can we do a delay send of these events or can we send an event before doing all this stuff that could calculate overhead? @@ -4025,7 +4063,7 @@ namespace Js HRESULT ScriptContext::RegisterLibraryFunction(const char16 *pwszObjectName, const char16 *pwszFunctionName, Js::PropertyId functionPropertyId, JavascriptMethod entryPoint) { -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) #if DEBUG const char16 *pwszObjectNameFromProperty = const_cast(GetPropertyName(functionPropertyId)->GetBuffer()); if (GetPropertyName(functionPropertyId)->IsSymbol()) diff --git a/lib/Runtime/Base/ScriptContext.h b/lib/Runtime/Base/ScriptContext.h index 3ee44486f73..a7480028469 100644 --- a/lib/Runtime/Base/ScriptContext.h +++ b/lib/Runtime/Base/ScriptContext.h @@ -4,7 +4,7 @@ //------------------------------------------------------------------------------------------------------- #pragma once -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(_WIN32) && defined(ENABLE_SCRIPT_PROFILING) #include "activprof.h" #endif @@ -492,9 +492,11 @@ namespace Js bool IsExceptionWrapperForBuiltInsEnabled(); static bool IsExceptionWrapperForBuiltInsEnabled(ScriptContext* scriptContext); static bool IsExceptionWrapperForHelpersEnabled(ScriptContext* scriptContext); -#ifdef ENABLE_SCRIPT_PROFILING bool IsEnumerateNonUserFunctionsOnly() const { return m_enumerateNonUserFunctionsOnly; } +#ifdef ENABLE_SCRIPT_PROFILING bool IsTraceDomCall() const { return !!m_fTraceDomCall; } +#elif defined(ENABLE_SCRIPT_DEBUGGING) + bool IsTraceDomCall() const { return false; } #endif InlineCache * GetValueOfInlineCache() const { return valueOfInlineCache;} @@ -1479,9 +1481,9 @@ namespace Js typedef HRESULT (*RegisterExternalLibraryType)(Js::ScriptContext *pScriptContext); #ifdef ENABLE_SCRIPT_PROFILING HRESULT RegisterProfileProbe(IActiveScriptProfilerCallback *pProfileCallback, DWORD dwEventMask, DWORD dwContext, RegisterExternalLibraryType RegisterExternalLibrary, JavascriptMethod dispatchInvoke); + HRESULT DeRegisterProfileProbe(HRESULT hrReason, JavascriptMethod dispatchInvoke); #endif HRESULT SetProfileEventMask(DWORD dwEventMask); - HRESULT DeRegisterProfileProbe(HRESULT hrReason, JavascriptMethod dispatchInvoke); HRESULT RegisterScript(Js::FunctionProxy *pFunctionBody, BOOL fRegisterScript = TRUE); @@ -1497,17 +1499,16 @@ namespace Js HRESULT RegisterLibraryFunction(const char16 *pwszObjectName, const char16 *pwszFunctionName, Js::PropertyId functionPropertyId, JavascriptMethod entryPoint); HRESULT RegisterBuiltinFunctions(RegisterExternalLibraryType RegisterExternalLibrary); - void RegisterDebugThunk(bool calledDuringAttach = true); - void UnRegisterDebugThunk(); - void UpdateRecyclerFunctionEntryPointsForDebugger(); void SetFunctionInRecyclerToProfileMode(bool enumerateNonUserFunctionsOnly = false); -#ifdef ENABLE_SCRIPT_PROFILING + +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) + void RegisterDebugThunk(bool calledDuringAttach = true); + void UnRegisterDebugThunk(); static void SetEntryPointToProfileThunk(JavascriptFunction* function); static void RestoreEntryPointFromProfileThunk(JavascriptFunction* function); -#endif - static void RecyclerEnumClassEnumeratorCallback(void *address, size_t size); +#endif static void RecyclerFunctionCallbackForDebugger(void *address, size_t size); static ushort ProcessNameAndGetLength(Js::StringBuilder* nameBuffer, const WCHAR* name); @@ -1597,10 +1598,13 @@ namespace Js static JavascriptMethod ProfileModeDeferredDeserialize(ScriptFunction* function); static Var ProfileModeDeferredDeserializeThunk(RecyclableObject* function, CallInfo callInfo, ...); +#if defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING) + static Var ProfileModeThunk_DebugModeWrapper(JavascriptFunction* function, ScriptContext* scriptContext, JavascriptMethod entryPoint, Arguments& args); + static JavascriptMethod GetProfileModeThunk(JavascriptMethod entryPoint); +#endif + #ifdef ENABLE_SCRIPT_PROFILING void SetProfileMode(BOOL fSet); - static JavascriptMethod GetProfileModeThunk(JavascriptMethod entryPoint); - static Var ProfileModeThunk_DebugModeWrapper(JavascriptFunction* function, ScriptContext* scriptContext, JavascriptMethod entryPoint, Arguments& args); BOOL GetProfileInfo( JavascriptFunction* function, PROFILER_TOKEN &scriptId, diff --git a/lib/Runtime/Base/Utf8SourceInfo.cpp b/lib/Runtime/Base/Utf8SourceInfo.cpp index 3d5ede4e00b..d0cbfbb0c64 100644 --- a/lib/Runtime/Base/Utf8SourceInfo.cpp +++ b/lib/Runtime/Base/Utf8SourceInfo.cpp @@ -411,7 +411,7 @@ namespace Js bool Utf8SourceInfo::GetDebugDocumentName(BSTR * sourceName) { -#ifdef ENABLE_SCRIPT_DEBUGGING +#if defined(ENABLE_SCRIPT_DEBUGGING) && defined(_WIN32) if (this->HasDebugDocument() && this->GetDebugDocument()->HasDocumentText()) { // ToDo (SaAgarwa): Fix for JsRT debugging diff --git a/lib/Runtime/Language/amd64/amd64_Thunks.S b/lib/Runtime/Language/amd64/amd64_Thunks.S index 6a1182f9788..aa61d6dd91b 100644 --- a/lib/Runtime/Language/amd64/amd64_Thunks.S +++ b/lib/Runtime/Language/amd64/amd64_Thunks.S @@ -118,47 +118,31 @@ NESTED_END _ZN2Js18DynamicProfileInfo29EnsureDynamicProfileInfoThunkEPNS_16Recyc #endif // _ENABLE_DYNAMIC_THUNKS -#ifdef ENABLE_SCRIPT_PROFILING - //============================================================================================================ // ScriptContext::ProfileModeDeferredParsingThunk //============================================================================================================ -// Js::JavascriptMethod ScriptContext::ProfileModeDeferredParse(ScriptFunction *function) -extrn ?ProfileModeDeferredParse@ScriptContext@Js@@SAP6APEAXPEAVRecyclableObject@2@UCallInfo@2@ZZPEAPEAVScriptFunction@2@@Z : PROC +// Js::JavascriptMethod ScriptContext::ProfileModeDeferredParse(ScriptFunction **function) +// extrn C_FUNC(_ZN2Js13ScriptContext31ProfileModeDeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz) // Var ScriptContext::ProfileModeDeferredParsingThunk(RecyclableObject* function, CallInfo callInfo, ...) -align 16 -?ProfileModeDeferredParsingThunk@ScriptContext@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ PROC FRAME - // save volatile registers - mov qword ptr [rsp + 8h], rcx - mov qword ptr [rsp + 10h], rdx - mov qword ptr [rsp + 18h], r8 - mov qword ptr [rsp + 20h], r9 - - push rbp - .pushreg rbp +.balign 16 +NESTED_ENTRY _ZN2Js13ScriptContext31ProfileModeDeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler + push_nonvol_reg rbp lea rbp, [rsp] - .setframe rbp, 0 - .endprolog - sub rsp, 20h - lea rcx, [rsp + 30h] - call C_FUNC(?ProfileModeDeferredParse@ScriptContext@Js@@SAP6APEAXPEAVRecyclableObject@2@UCallInfo@2@ZZPEAPEAVScriptFunction@2@@Z) - - add rsp, 20h + // save argument registers used by custom calling convention + push_register rdi + push_register rsi - lea rsp, [rbp] - pop rbp + call C_FUNC(_ZN2Js13ScriptContext24ProfileModeDeferredParseEPPNS_14ScriptFunctionE) - // restore volatile registers - mov rcx, qword ptr [rsp + 8h] - mov rdx, qword ptr [rsp + 10h] - mov r8, qword ptr [rsp + 18h] - mov r9, qword ptr [rsp + 20h] + pop_register rsi + pop_register rdi - rex_jmp_reg rax -?ProfileModeDeferredParsingThunk@ScriptContext@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ ENDP + pop_nonvol_reg rbp + jmp rax +NESTED_END _ZN2Js13ScriptContext31ProfileModeDeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT //============================================================================================================ @@ -168,41 +152,26 @@ align 16 //============================================================================================================ // Js::JavascriptMethod ScriptContext::ProfileModeDeferredDeserialize(ScriptFunction *function) -extrn ?ProfileModeDeferredDeserialize@ScriptContext@Js@@SAP6APEAXPEAVRecyclableObject@2@UCallInfo@2@ZZPEAVScriptFunction@2@@Z : PROC +// extrn ?ProfileModeDeferredDeserialize@ScriptContext@Js@@SAP6APEAXPEAVRecyclableObject@2@UCallInfo@2@ZZPEAVScriptFunction@2@@Z : PROC // Var ScriptContext::ProfileModeDeferredDeserializeThunk(RecyclableObject* function, CallInfo callInfo, ...) -align 16 -?ProfileModeDeferredDeserializeThunk@ScriptContext@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ PROC FRAME - // save volatile registers - mov qword ptr [rsp + 8h], rcx - mov qword ptr [rsp + 10h], rdx - mov qword ptr [rsp + 18h], r8 - mov qword ptr [rsp + 20h], r9 - - push rbp - .pushreg rbp +.balign 16 +NESTED_ENTRY _ZN2Js13ScriptContext35ProfileModeDeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler + push_nonvol_reg rbp lea rbp, [rsp] - .setframe rbp, 0 - .endprolog - - sub rsp, 20h - call C_FUNC(?ProfileModeDeferredDeserialize@ScriptContext@Js@@SAP6APEAXPEAVRecyclableObject@2@UCallInfo@2@ZZPEAVScriptFunction@2@@Z) - - add rsp, 20h - lea rsp, [rbp] - pop rbp + // save argument registers used by custom calling convention + push_register rdi + push_register rsi - // restore volatile registers - mov rcx, qword ptr [rsp + 8h] - mov rdx, qword ptr [rsp + 10h] - mov r8, qword ptr [rsp + 18h] - mov r9, qword ptr [rsp + 20h] + call C_FUNC(_ZN2Js13ScriptContext30ProfileModeDeferredDeserializeEPNS_14ScriptFunctionE) - rex_jmp_reg rax -?ProfileModeDeferredDeserializeThunk@ScriptContext@Js@@SAPEAXPEAVRecyclableObject@2@UCallInfo@2@ZZ ENDP + pop_register rsi + pop_register rdi -#endif // ENABLE_SCRIPT_PROFILING + pop_nonvol_reg rbp + jmp rax +NESTED_END _ZN2Js13ScriptContext35ProfileModeDeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT #ifdef _ENABLE_DYNAMIC_THUNKS diff --git a/lib/Runtime/Library/JavascriptFunction.cpp b/lib/Runtime/Library/JavascriptFunction.cpp index ce524e59c72..0e45249bdc0 100644 --- a/lib/Runtime/Library/JavascriptFunction.cpp +++ b/lib/Runtime/Library/JavascriptFunction.cpp @@ -1122,23 +1122,23 @@ namespace Js #if _M_IX86 #ifdef ASMJS_PLAT - template <> int JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) + template <> int JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) { return CallAsmJsFunctionX86Thunk(function, entryPoint, argc, argv).retIntVal; } - template <> int64 JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) + template <> int64 JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) { return CallAsmJsFunctionX86Thunk(function, entryPoint, argc, argv).retInt64Val; } - template <> float JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) + template <> float JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) { return CallAsmJsFunctionX86Thunk(function, entryPoint, argc, argv).retFloatVal; } - template <> double JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) + template <> double JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) { return CallAsmJsFunctionX86Thunk(function, entryPoint, argc, argv).retDoubleVal; } - template <> AsmJsSIMDValue JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) + template <> AsmJsSIMDValue JavascriptFunction::CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv) { return CallAsmJsFunctionX86Thunk(function, entryPoint, argc, argv).retSimdVal; } @@ -1149,7 +1149,7 @@ namespace Js IsFloat = 1 << AsmJsRetType::Float, IsDouble = 1 << AsmJsRetType::Double, IsInt64 = 1 << AsmJsRetType::Int64, - IsSimd = + IsSimd = 1 << AsmJsRetType::Int32x4 | 1 << AsmJsRetType::Bool32x4 | 1 << AsmJsRetType::Bool16x8 | @@ -1677,10 +1677,10 @@ void __cdecl _alloca_probe_16() } DebugOnly(JavascriptMethod directEntryPoint = funcBody->GetDirectEntryPoint(funcBody->GetDefaultEntryPointInfo())); -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Assert(directEntryPoint != DefaultDeferredParsingThunk && directEntryPoint != ProfileDeferredParsingThunk); -#else // !ENABLE_SCRIPT_PROFILING +#else // !ENABLE_SCRIPT_PROFILING && !ENABLE_SCRIPT_DEBUGGING Assert(directEntryPoint != DefaultDeferredParsingThunk); #endif diff --git a/lib/Runtime/Library/JavascriptFunction.h b/lib/Runtime/Library/JavascriptFunction.h index 4ea6e71988c..ca1dbdfadf3 100644 --- a/lib/Runtime/Library/JavascriptFunction.h +++ b/lib/Runtime/Library/JavascriptFunction.h @@ -101,8 +101,10 @@ namespace Js Var CallFunction(Arguments args); Var CallRootFunction(Arguments args, ScriptContext * scriptContext, bool inScript); Var CallRootFunctionInternal(Arguments args, ScriptContext * scriptContext, bool inScript); +#ifdef ASMJS_PLAT template static T CallAsmJsFunction(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv); +#endif static PossibleAsmJsReturnValues CallAsmJsFunctionX86Thunk(RecyclableObject * function, JavascriptMethod entryPoint, uint argc, Var * argv); template static Var CalloutHelper(RecyclableObject* function, Var thisArg, Var overridingNewTarget, Var argArray, ScriptContext* scriptContext); diff --git a/lib/Runtime/Library/ScriptFunction.cpp b/lib/Runtime/Library/ScriptFunction.cpp index b5b99344f0f..f052275c0c9 100644 --- a/lib/Runtime/Library/ScriptFunction.cpp +++ b/lib/Runtime/Library/ScriptFunction.cpp @@ -287,7 +287,7 @@ namespace Js // The type has change from the default, it is not share, just use that one. JavascriptMethod directEntryPoint = newFunctionInfo->GetDirectEntryPoint(newFunctionInfo->GetDefaultEntryPointInfo()); -#ifdef ENABLE_SCRIPT_PROFILING +#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING) Assert(directEntryPoint != DefaultDeferredParsingThunk && directEntryPoint != ProfileDeferredParsingThunk); #else @@ -558,7 +558,7 @@ namespace Js { case Js::ScopeType::ScopeType_ActivationObject: case Js::ScopeType::ScopeType_WithScope: - { + { rctxInfo->EnqueueNewPathVarAsNeeded(this, (Js::Var)scope, scopePathString.GetStrValue()); break; } @@ -658,14 +658,14 @@ namespace Js bool AsmJsScriptFunction::Is(Var func) { - return ScriptFunction::Is(func) && + return ScriptFunction::Is(func) && ScriptFunction::FromVar(func)->HasFunctionBody() && ScriptFunction::FromVar(func)->GetFunctionBody()->GetIsAsmJsFunction(); } bool AsmJsScriptFunction::IsWasmScriptFunction(Var func) { - return ScriptFunction::Is(func) && + return ScriptFunction::Is(func) && ScriptFunction::FromVar(func)->HasFunctionBody() && ScriptFunction::FromVar(func)->GetFunctionBody()->IsWasmFunction(); } diff --git a/lib/Runtime/Library/WebAssembly.cpp b/lib/Runtime/Library/WebAssembly.cpp index 179d4d2a3ed..7ec6983fa56 100644 --- a/lib/Runtime/Library/WebAssembly.cpp +++ b/lib/Runtime/Library/WebAssembly.cpp @@ -185,4 +185,4 @@ WebAssembly::GetSignatureSize() } } -#endif // ENABLE_WASM \ No newline at end of file +#endif // ENABLE_WASM diff --git a/lib/Runtime/Library/amd64/JavascriptFunctionA.S b/lib/Runtime/Library/amd64/JavascriptFunctionA.S index d655f3c553d..ef39b1af0ea 100644 --- a/lib/Runtime/Library/amd64/JavascriptFunctionA.S +++ b/lib/Runtime/Library/amd64/JavascriptFunctionA.S @@ -256,8 +256,6 @@ LEAF_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIdEET_PNS_16RecyclableOb LEAF_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIdEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEjPS5_, _TEXT #endif // _ENABLE_DYNAMIC_THUNKS - - //------------------------------------------------------------------------------ .balign 16 NESTED_ENTRY _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler diff --git a/lib/Runtime/Runtime.h b/lib/Runtime/Runtime.h index 9a1f41a63f7..e9254a4eade 100644 --- a/lib/Runtime/Runtime.h +++ b/lib/Runtime/Runtime.h @@ -349,7 +349,7 @@ const Js::ModuleID kmodGlobal = 0; class SourceContextInfo; -#ifdef ENABLE_SCRIPT_DEBUGGING +#if defined(ENABLE_SCRIPT_DEBUGGING) && defined(_WIN32) #include "activdbg100.h" #endif diff --git a/test/Debugger/MultipleContextStack.js b/test/Debugger/MultipleContextStack.js index af4726c9bfc..5fa81da5126 100644 --- a/test/Debugger/MultipleContextStack.js +++ b/test/Debugger/MultipleContextStack.js @@ -21,8 +21,8 @@ var script1 = WScript.LoadScript("\ function Script1Func3() { scriptFunc3(); } \ function setFunc2(func) { scriptFunc2 = func; } \ function setFunc3(func) { scriptFunc3 = func; }", - "samethread", "Script1.js"); - + "samethread"); + var script2 = WScript.LoadScript(" \ var script1Func2; \ var script1Func3; \ @@ -31,8 +31,8 @@ var script2 = WScript.LoadScript(" \ function Script2Func3() { script1Func3(); } \ function setFunc2(func) { script1Func2 = func; } \ function setFunc3(func) { script1Func3 = func; }", - "samethread", "Script2.js"); - + "samethread"); + function Func2() { Func1(); } diff --git a/test/Debugger/rlexe.xml b/test/Debugger/rlexe.xml index 7401a3aad97..e8f0662b58e 100644 --- a/test/Debugger/rlexe.xml +++ b/test/Debugger/rlexe.xml @@ -16,6 +16,8 @@ -debuglaunch -dbgbaseline:JsDiagGetFunctionPosition.js.dbg.baseline JsDiagGetFunctionPosition.js + + exclude_xplat diff --git a/test/DebuggerCommon/array_protoTest.js.dbg.baseline b/test/DebuggerCommon/array_prototest.js.dbg.baseline similarity index 100% rename from test/DebuggerCommon/array_protoTest.js.dbg.baseline rename to test/DebuggerCommon/array_prototest.js.dbg.baseline diff --git a/test/DebuggerCommon/rlexe.xml b/test/DebuggerCommon/rlexe.xml index d84c04e4607..57ff0d70154 100644 --- a/test/DebuggerCommon/rlexe.xml +++ b/test/DebuggerCommon/rlexe.xml @@ -37,7 +37,8 @@ ES6_intl_stepinto.js -dbgbaseline:ES6_intl_stepinto.js.dbg.baseline -Intl ES6_intl_stepinto.js.baseline - fail_mutators,exclude_winglob + + fail_mutators,exclude_winglob,exclude_xplat @@ -242,7 +243,8 @@ ES6_intl_simple_attach.js -dbgbaseline:ES6_intl_simple_attach.js.dbg.baseline -Intl ES6_intl_simple_attach.js.baseline - fail_mutators,exclude_winglob + + fail_mutators,exclude_winglob,exclude_xplat @@ -324,7 +326,8 @@ ES6_intl_stepinto_libexpandos.js -debuglaunch -dbgbaseline:ES6_intl_stepinto_libexpandos.js.dbg.baseline -Intl - fail_mutators,exclude_winglob + + fail_mutators,exclude_winglob,exclude_xplat @@ -513,7 +516,7 @@ - array_protoTest.js + array_prototest.js -debuglaunch -dbgbaseline:array_prototest.js.dbg.baseline fail_mutators @@ -571,7 +574,8 @@ attachdetach-delaycapture.js -dbgbaseline:attachdetach-delaycapture.js.dbg.baseline - BugFix + + BugFix,exclude_xplat @@ -997,7 +1001,7 @@ - + jitAttach.js -maxinterpretcount:1 -off:simpleJit -EnableJitInDiagMode -dbgbaseline:jitAttach.js.dbg.baseline fail_mutators,exclude_dynapogo @@ -1278,14 +1282,16 @@ returnedvaluetests1.js -dbgbaseline:returnedvaluetests1.js.dbg.baseline - exclude_dynapogo,exclude_serialized + + exclude_dynapogo,exclude_serialized,exclude_xplat returnedvaluetests2.js -debugLaunch -dbgbaseline:returnedvaluetests2.js.dbg.baseline - exclude_dynapogo,exclude_serialized + + exclude_dynapogo,exclude_serialized,exclude_xplat @@ -1378,6 +1384,8 @@ TypedArray.js -ES6Species -debuglaunch -dbgbaseline:typedarray.js.dbg.baseline -InspectMaxStringLength:200 + + exclude_xplat diff --git a/test/runtests.py b/test/runtests.py index aa664618d90..bb230d2ff0d 100755 --- a/test/runtests.py +++ b/test/runtests.py @@ -121,7 +121,7 @@ if sys.platform != 'win32': not_tags.add('exclude_xplat') not_tags.add('Intl') - not_tags.add('require_debugger') + if sys.platform == 'darwin': not_tags.add('exclude_mac') not_compile_flags = set(['-simdjs']) \