Skip to content

Commit f49682b

Browse files
Etienne BAUDOUXmeg-gupta
authored andcommitted
Making the JS Built-in inlining.
1 parent 8e6b81f commit f49682b

24 files changed

Lines changed: 2017 additions & 1700 deletions

lib/Backend/GlobOpt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3571,6 +3571,7 @@ GlobOpt::OptSrc(IR::Opnd *opnd, IR::Instr * *pInstr, Value **indirIndexValRef, I
35713571
ChangeValueType(this->currentBlock, CurrentBlockData()->FindValue(opnd->AsRegOpnd()->m_sym), valueType, false);
35723572
}
35733573
}
3574+
35743575
opnd->SetValueType(valueType);
35753576

35763577
if(!IsLoopPrePass() && opnd->IsSymOpnd() && valueType.IsDefinite())

lib/Backend/InliningDecider.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ bool InliningDecider::InlineIntoInliner(Js::FunctionBody *const inliner) const
6969
return false;
7070
}
7171

72-
if (!Js::DynamicProfileInfo::HasCallSiteInfo(inliner))
72+
if (!inliner->IsJsBuiltInCode() && !inliner->GetAnyDynamicProfileInfo()->HasCallSiteInfo(inliner))
7373
{
7474
INLINE_TESTTRACE(_u("INLINING: Skip Inline: No call site info\tCaller: %s (#%d)\n"), inliner->GetDisplayName(),
7575
inliner->GetDebugNumberSet(debugStringBuffer));
@@ -498,7 +498,7 @@ bool InliningDecider::GetBuiltInInfoCommon(
498498
*returnType = ValueType::Boolean;
499499
goto CallDirectCommon;
500500

501-
case Js::JavascriptBuiltInFunction::JavascriptArray_IndexOf:
501+
//case Js::JavascriptBuiltInFunction::JavascriptArray_IndexOf:
502502
case Js::JavascriptBuiltInFunction::JavascriptArray_LastIndexOf:
503503
case Js::JavascriptBuiltInFunction::JavascriptArray_Unshift:
504504
case Js::JavascriptBuiltInFunction::JavascriptString_CharCodeAt:

lib/Backend/NativeCodeGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3599,7 +3599,7 @@ bool NativeCodeGenerator::TryAggressiveInlining(Js::FunctionBody *const topFunct
35993599
bool isConstructorCall = false;
36003600
bool isPolymorphicCall = false;
36013601

3602-
if (!inliningDecider.HasCallSiteInfo(inlineeFunctionBody, profiledCallSiteId))
3602+
if (!inlineeFunctionBody->IsJsBuiltInCode() && !inliningDecider.HasCallSiteInfo(inlineeFunctionBody, profiledCallSiteId))
36033603
{
36043604
//There is no callsite information. We should hit bailonnoprofile for these callsites. Ignore.
36053605
continue;

lib/Parser/ParseFlags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ enum
3434
fscrAllowFunctionProxy = 1 << 17, // Allow creation of function proxies instead of function bodies
3535
fscrIsLibraryCode = 1 << 18, // Current code is engine library code written in Javascript
3636
fscrNoDeferParse = 1 << 19, // Do not defer parsing
37-
// Unused = 1 << 20,
37+
fscrJsBuiltIn = 1 << 20, // Current code is a JS built in code written in JavaScript
3838
#ifdef IR_VIEWER
3939
fscrIrDumpEnable = 1 << 21, // Allow parseIR to generate an IR dump
4040
#endif /* IRVIEWER */

lib/Runtime/Base/Constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace Js
1818
// Id of the NoContextSourceContextInfo
1919
static const uint NoSourceContext = (uint)-1;
2020
// Variable indicating no source context cookie was passed in by the host- indicates Dynamic Script
21+
static const DWORD_PTR JsBuiltInSourceContext = (DWORD_PTR)-2;
2122
static const DWORD_PTR NoHostSourceContext = (DWORD_PTR)-1;
2223
static const DWORD_PTR FunctionBodyUnavailable = (DWORD_PTR)NULL; // Not a valid Var
2324
static const LocalFunctionId NoFunctionId = (LocalFunctionId)-1;

lib/Runtime/Base/FunctionBody.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3046,7 +3046,7 @@ namespace Js
30463046

30473047
bool FunctionBody::GetLineCharOffsetFromStartChar(int startCharOfStatement, ULONG* _line, LONG* _charOffset, bool canAllocateLineCache /*= true*/)
30483048
{
3049-
Assert(!this->GetUtf8SourceInfo()->GetIsLibraryCode());
3049+
//Assert(!this->GetUtf8SourceInfo()->GetIsLibraryCode());
30503050

30513051
// The following adjusts for where the script is within the document
30523052
ULONG line = this->GetHostStartLine();

lib/Runtime/Base/FunctionBody.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,9 @@ namespace Js
12911291
void SetIsPublicLibraryCode() { m_isPublicLibraryCode = true; }
12921292
bool IsPublicLibraryCode() const { return m_isPublicLibraryCode; }
12931293

1294+
void SetIsJsBuiltInCode() { m_isJsBuiltInCode = true; }
1295+
bool IsJsBuiltInCode() const { return m_isJsBuiltInCode; }
1296+
12941297
#if DBG
12951298
bool HasValidEntryPoint() const;
12961299
#if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING)
@@ -1350,6 +1353,7 @@ namespace Js
13501353

13511354
FieldWithBarrier(bool) m_isTopLevel : 1; // Indicates that this function is top-level function, currently being used in script profiler and debugger
13521355
FieldWithBarrier(bool) m_isPublicLibraryCode: 1; // Indicates this function is public boundary library code that should be visible in JS stack
1356+
FieldWithBarrier(bool) m_isJsBuiltInCode: 1; // Indicates this function comes from the JS Built In implementation
13531357
FieldWithBarrier(bool) m_canBeDeferred : 1;
13541358
FieldWithBarrier(bool) m_displayNameIsRecyclerAllocated : 1;
13551359

lib/Runtime/Base/JnDirectFields.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ ENTRY(MissingProperty)
720720
ENTRY(winglob)
721721
//Built In
722722
ENTRY(__chakraLibrary)
723+
ENTRY(registerChakraLibraryFunction)
723724
ENTRY(registerFunction)
724725
ENTRY(className)
725726
ENTRY(methodName)

lib/Runtime/ByteCode/ByteCodeSerializer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,8 +4326,9 @@ HRESULT ByteCodeSerializer::DeserializeFromBufferInternal(ScriptContext * script
43264326

43274327
auto alloc = scriptContext->SourceCodeAllocator();
43284328
bool isLibraryCode = ((scriptFlags & fscrIsLibraryCode) == fscrIsLibraryCode);
4329-
int builtInPropertyCount = isLibraryCode ? PropertyIds::_countJSOnlyProperty : TotalNumberOfBuiltInProperties;
4330-
auto reader = Anew(alloc, ByteCodeBufferReader, scriptContext, buffer, isLibraryCode, builtInPropertyCount);
4329+
bool isJsBuiltInCode = ((scriptFlags & fscrJsBuiltIn) == fscrJsBuiltIn);
4330+
int builtInPropertyCount = isLibraryCode || isJsBuiltInCode ? PropertyIds::_countJSOnlyProperty : TotalNumberOfBuiltInProperties;
4331+
auto reader = Anew(alloc, ByteCodeBufferReader, scriptContext, buffer, isLibraryCode || isJsBuiltInCode, builtInPropertyCount);
43314332
auto hr = reader->ReadHeader();
43324333
if (FAILED(hr))
43334334
{
@@ -4346,7 +4347,7 @@ HRESULT ByteCodeSerializer::DeserializeFromBufferInternal(ScriptContext * script
43464347
}
43474348

43484349
sourceInfo = Js::Utf8SourceInfo::NewWithHolder(scriptContext, sourceHolder,
4349-
reader->sourceCharLength, pinnedSrcInfo, isLibraryCode);
4350+
reader->sourceCharLength, pinnedSrcInfo, isLibraryCode || isJsBuiltInCode);
43504351

43514352
reader->utf8SourceInfo = sourceInfo;
43524353
reader->sourceIndex = scriptContext->SaveSourceNoCopy(sourceInfo, reader->sourceCharLength, false);

lib/Runtime/Language/DynamicProfileInfo.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,11 @@ namespace Js
573573
}
574574
functionId = calleeFunctionProxy->GetLocalFunctionId();
575575
}
576+
else if (calleeFunctionProxy->GetHostSourceContext() == Js::Constants::JsBuiltInSourceContext)
577+
{
578+
sourceId = JsBuiltInSourceId;
579+
functionId = calleeFunctionProxy->GetLocalFunctionId();
580+
}
576581
else
577582
{
578583
// Pretend that we are cross context when call is crossing script file.
@@ -768,7 +773,7 @@ namespace Js
768773
Assert(functionBody);
769774
const auto callSiteCount = functionBody->GetProfiledCallSiteCount();
770775
Assert(callSiteId < callSiteCount);
771-
Assert(HasCallSiteInfo(functionBody));
776+
Assert(functionBody->IsJsBuiltInCode() || HasCallSiteInfo(functionBody));
772777
Assert(functionBodyArray);
773778
Assert(functionBodyArrayLength == DynamicProfileInfo::maxPolymorphicInliningSize);
774779

@@ -859,7 +864,7 @@ namespace Js
859864
Assert(functionBody);
860865
const auto callSiteCount = functionBody->GetProfiledCallSiteCount();
861866
Assert(callSiteId < callSiteCount);
862-
Assert(HasCallSiteInfo(functionBody));
867+
Assert(functionBody->IsJsBuiltInCode() || HasCallSiteInfo(functionBody));
863868

864869
*isConstructorCall = callSiteInfo[callSiteId].isConstructorCall;
865870
if (callSiteInfo[callSiteId].dontInline)
@@ -875,12 +880,37 @@ namespace Js
875880
return JavascriptBuiltInFunction::GetFunctionInfo(functionId);
876881
}
877882

878-
if (sourceId == CurrentSourceId) // caller and callee in same file
883+
if (sourceId == CurrentSourceId) // caller and callee in same file
879884
{
880885
FunctionProxy *inlineeProxy = functionBody->GetUtf8SourceInfo()->FindFunction(functionId);
881886
return inlineeProxy ? inlineeProxy->GetFunctionInfo() : nullptr;
882887
}
883888

889+
if (sourceId == JsBuiltInSourceId)
890+
{
891+
// For call across files find the function from the right source
892+
JsUtil::List<RecyclerWeakReference<Utf8SourceInfo>*, Recycler, false, Js::FreeListedRemovePolicy> * sourceList = functionBody->GetScriptContext()->GetSourceList();
893+
for (int i = 0; i < sourceList->Count(); i++)
894+
{
895+
if (sourceList->IsItemValid(i))
896+
{
897+
Utf8SourceInfo *srcInfo = sourceList->Item(i)->Get();
898+
if (srcInfo && srcInfo->GetHostSourceContext() == Js::Constants::JsBuiltInSourceContext)
899+
{
900+
FunctionProxy *inlineeProxy = srcInfo->FindFunction(functionId);
901+
if (inlineeProxy && inlineeProxy->IsJsBuiltInCode())
902+
{
903+
return inlineeProxy->GetFunctionInfo();
904+
}
905+
else
906+
{
907+
return nullptr;
908+
}
909+
}
910+
}
911+
}
912+
}
913+
884914
if (sourceId != NoSourceId && sourceId != InvalidSourceId)
885915
{
886916
// For call across files find the function from the right source
@@ -911,7 +941,7 @@ namespace Js
911941
Assert(functionBody);
912942
const auto callSiteCount = functionBody->GetProfiledCallSiteCount();
913943
Assert(callSiteId < callSiteCount);
914-
Assert(HasCallSiteInfo(functionBody));
944+
Assert(functionBody->IsJsBuiltInCode() || HasCallSiteInfo(functionBody));
915945

916946
return callSiteInfo[callSiteId].ldFldInlineCacheId;
917947
}

0 commit comments

Comments
 (0)