Skip to content

Commit

Permalink
[MERGE #5727 @sharmasuraj0123] Fixes #5201: Implemented StringTemplat…
Browse files Browse the repository at this point in the history
…e Caching based on location in source Code.

Merge pull request #5727 from sharmasuraj0123:StringTemplateCaching

Changed the earlier implementation of caching the StringTemplates based
on Raw String Literals to their location in the source code.

Old Behavior:

```js
function getCallsite(c) { return c; }
function getFooCallsite() { return getCallsite`foo`; }
print(getFooCallsite() === getFooCallsite()); // true
print(getCallsite`foo` === getCallsite`foo`); // true
print(getCallsite`foo` === eval('getCallsite`foo`')); // true
```

New Behavior:

```js
function getCallsite(c) { return c; }
function getFooCallsite() { return getCallsite`foo`; }
print(getFooCallsite() === getFooCallsite()); // true
print(getCallsite`foo` === getCallsite`foo`); // false
print(getCallsite`foo` === eval('getCallsite`foo`')); // false
```

Deleted the added mapping that would compare and ensure that the two callsite objects are equal based on their raw String literals.
Now it store every diferent pnode object it comes accross and assigns it a register.

Fixes #5201
  • Loading branch information
sharmasuraj0123 committed Sep 25, 2018
2 parents 6a9b83b + f8023f7 commit 10a6930
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 472 deletions.
19 changes: 6 additions & 13 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5692,20 +5692,13 @@ void ByteCodeGenerator::RecordAllStringTemplateCallsiteConstants(FuncInfo* funcI
funcInfo->stringTemplateCallsiteRegisterMap.Map([byteCodeFunction](ParseNodePtr pnode, Js::RegSlot location)
{
Js::ScriptContext* scriptContext = byteCodeFunction->GetScriptContext();
Js::JavascriptLibrary* library = scriptContext->GetLibrary();
Js::RecyclableObject* callsiteObject = library->TryGetStringTemplateCallsiteObject(pnode);

if (callsiteObject == nullptr)
{
Js::RecyclableObject* rawArray = ByteCodeGenerator::BuildArrayFromStringList(pnode->AsParseNodeStrTemplate()->pnodeStringRawLiterals, pnode->AsParseNodeStrTemplate()->countStringLiterals, scriptContext);
rawArray->Freeze();

callsiteObject = ByteCodeGenerator::BuildArrayFromStringList(pnode->AsParseNodeStrTemplate()->pnodeStringLiterals, pnode->AsParseNodeStrTemplate()->countStringLiterals, scriptContext);
callsiteObject->SetPropertyWithAttributes(Js::PropertyIds::raw, rawArray, PropertyNone, nullptr);
callsiteObject->Freeze();

Js::RecyclableObject* rawArray = ByteCodeGenerator::BuildArrayFromStringList(pnode->AsParseNodeStrTemplate()->pnodeStringRawLiterals, pnode->AsParseNodeStrTemplate()->countStringLiterals, scriptContext);
rawArray->Freeze();

library->AddStringTemplateCallsiteObject(callsiteObject);
}
Js::RecyclableObject* callsiteObject = ByteCodeGenerator::BuildArrayFromStringList(pnode->AsParseNodeStrTemplate()->pnodeStringLiterals, pnode->AsParseNodeStrTemplate()->countStringLiterals, scriptContext);
callsiteObject->SetPropertyWithAttributes(Js::PropertyIds::raw, rawArray, PropertyNone, nullptr);
callsiteObject->Freeze();

byteCodeFunction->RecordConstant(byteCodeFunction->MapRegSlot(location), callsiteObject);
});
Expand Down
11 changes: 1 addition & 10 deletions lib/Runtime/ByteCode/ByteCodeSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3210,16 +3210,7 @@ class ByteCodeBufferReader
callsite->SetPropertyWithAttributes(Js::PropertyIds::raw, rawArray, PropertyNone, nullptr);
callsite->Freeze();

JavascriptLibrary* library = scriptContext->GetLibrary();

var = library->TryGetStringTemplateCallsiteObject(callsite);

if (var == nullptr)
{
library->AddStringTemplateCallsiteObject(callsite);
var = callsite;
}

var = callsite;
LEAVE_PINNED_SCOPE();

return current;
Expand Down
2 changes: 1 addition & 1 deletion lib/Runtime/ByteCode/FuncInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class FuncInfo
typedef JsUtil::BaseDictionary<double,Js::RegSlot, ArenaAllocator, PrimeSizePolicy> DoubleRegisterMap;
DoubleRegisterMap doubleConstantToRegister; // maps double constant to register

typedef JsUtil::BaseDictionary<ParseNodePtr, Js::RegSlot, ArenaAllocator, PowerOf2SizePolicy, Js::StringTemplateCallsiteObjectComparer> StringTemplateCallsiteRegisterMap;
typedef JsUtil::BaseDictionary<ParseNodePtr, Js::RegSlot, ArenaAllocator, PowerOf2SizePolicy> StringTemplateCallsiteRegisterMap;
StringTemplateCallsiteRegisterMap stringTemplateCallsiteRegisterMap; // maps string template callsite constant to register

Scope *paramScope; // top level scope for parameter default values
Expand Down
Loading

0 comments on commit 10a6930

Please sign in to comment.