Skip to content

Commit 1a88201

Browse files
committed
[MERGE #5920 @MikeHolman] change initial type to prevent conversions when creating bound function
Merge pull request #5920 from MikeHolman:boundtype When creating bound functions, we add a length property, which causes conversion from SimpleTypeHandler, which could be very expensive. This changes to use a SimpleTypeHandler that has a length property. This improves react by about 20%.
2 parents 08161b0 + 33a3dc4 commit 1a88201

File tree

5 files changed

+40
-30
lines changed

5 files changed

+40
-30
lines changed

lib/Runtime/Library/JavascriptExternalFunction.cpp

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

5959
bool __cdecl JavascriptExternalFunction::DeferredLengthInitializer(DynamicObject * instance, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
6060
{
61-
Js::JavascriptLibrary::InitializeFunction<true, true, true>(instance, typeHandler, mode);
61+
Js::JavascriptLibrary::InitializeFunction<true, true, true, true>(instance, typeHandler, mode);
6262

6363
JavascriptExternalFunction* object = static_cast<JavascriptExternalFunction*>(instance);
6464

lib/Runtime/Library/JavascriptLibrary.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ namespace Js
594594
Js::DeferredTypeHandler<Js::JavascriptExternalFunction::DeferredConstructorInitializer>::GetDefaultInstance(), true, true);
595595

596596
boundFunctionType = DynamicType::New(scriptContext, TypeIds_Function, functionPrototype, BoundFunction::NewInstance,
597-
GetDeferredFunctionTypeHandler(), true, true);
597+
GetDeferredFunctionWithLengthUnsetTypeHandler(), true, true);
598598
crossSiteDeferredFunctionType = CreateDeferredFunctionTypeNoProfileThunk(
599599
scriptContext->CurrentCrossSiteThunk, true /*isShared*/);
600600
crossSiteDeferredPrototypeFunctionType = CreateDeferredPrototypeFunctionTypeNoProfileThunk(
@@ -784,7 +784,7 @@ namespace Js
784784
JavascriptArray::EnsureCalculationOfAllocationBuckets<Js::JavascriptArray>();
785785
}
786786

787-
template<bool addPrototype, bool addName, bool useLengthType>
787+
template<bool addPrototype, bool addName, bool useLengthType, bool addLength>
788788
bool JavascriptLibrary::InitializeFunction(DynamicObject *instance, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
789789
{
790790
JavascriptFunction * function = VarTo<JavascriptFunction>(instance);
@@ -833,7 +833,8 @@ namespace Js
833833
{
834834
ParseableFunctionInfo * funcInfo = scriptFunction->GetFunctionProxy()->EnsureDeserialized();
835835

836-
if (useLengthType)
836+
CompileAssert(!addLength || useLengthType);
837+
if (addLength)
837838
{
838839
function->SetPropertyWithAttributes(PropertyIds::length, TaggedInt::ToVarUnchecked(funcInfo->GetReportedInParamsCount() - 1), PropertyConfigurable, nullptr, PropertyOperation_None, SideEffects_None);
839840
}
@@ -914,10 +915,10 @@ namespace Js
914915
}
915916
};
916917

917-
template<bool isNameAvailable, bool isPrototypeAvailable, bool isLengthAvailable>
918+
template<bool isNameAvailable, bool isPrototypeAvailable, bool isLengthAvailable, bool addLength>
918919
DynamicTypeHandler * JavascriptLibrary::GetDeferredFunctionTypeHandlerBase()
919920
{
920-
return DeferredTypeHandler<InitializeFunction<isPrototypeAvailable, isNameAvailable, isLengthAvailable>, InitializeFunctionDeferredTypeHandlerFilter<isNameAvailable, isPrototypeAvailable, isLengthAvailable>>::GetDefaultInstance();
921+
return DeferredTypeHandler<InitializeFunction<isPrototypeAvailable, isNameAvailable, isLengthAvailable, addLength>, InitializeFunctionDeferredTypeHandlerFilter<isNameAvailable, isPrototypeAvailable, isLengthAvailable>>::GetDefaultInstance();
921922
}
922923

923924
template<bool isNameAvailable, bool isPrototypeAvailable>
@@ -993,6 +994,11 @@ namespace Js
993994
return GetDeferredFunctionTypeHandlerBase</*isNameAvailable*/ true, /*isPrototypeAvailable*/ false, /* isLengthAvailable */ true>();
994995
}
995996

997+
DynamicTypeHandler * JavascriptLibrary::GetDeferredFunctionWithLengthUnsetTypeHandler()
998+
{
999+
return GetDeferredFunctionTypeHandlerBase</*isNameAvailable*/ true, /*isPrototypeAvailable*/ false, /* isLengthAvailable */ true, /* addLength */ false>();
1000+
}
1001+
9961002
DynamicTypeHandler * JavascriptLibrary::ScriptFunctionTypeHandler(bool noPrototypeProperty, bool isAnonymousFunction)
9971003
{
9981004
DynamicTypeHandler * scriptFunctionTypeHandler = nullptr;

lib/Runtime/Library/JavascriptLibrary.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,11 +902,12 @@ namespace Js
902902

903903
DynamicTypeHandler * GetDeferredFunctionTypeHandler();
904904
DynamicTypeHandler * GetDeferredFunctionWithLengthTypeHandler();
905+
DynamicTypeHandler* GetDeferredFunctionWithLengthUnsetTypeHandler();
905906
DynamicTypeHandler * GetDeferredPrototypeFunctionWithNameAndLengthTypeHandler();
906907
DynamicTypeHandler * ScriptFunctionTypeHandler(bool noPrototypeProperty, bool isAnonymousFunction);
907908
DynamicTypeHandler * GetDeferredAnonymousFunctionWithLengthTypeHandler();
908909
DynamicTypeHandler * GetDeferredAnonymousFunctionTypeHandler();
909-
template<bool isNameAvailable, bool isPrototypeAvailable = true, bool isLengthAvailable = false>
910+
template<bool isNameAvailable, bool isPrototypeAvailable = true, bool isLengthAvailable = false, bool addLength = isLengthAvailable>
910911
static DynamicTypeHandler * GetDeferredFunctionTypeHandlerBase();
911912
template<bool isNameAvailable, bool isPrototypeAvailable = true>
912913
static DynamicTypeHandler * GetDeferredGeneratorFunctionTypeHandlerBase();
@@ -1236,7 +1237,7 @@ namespace Js
12361237
#endif
12371238

12381239
public:
1239-
template<bool addPrototype, bool addName, bool useLengthType>
1240+
template<bool addPrototype, bool addName, bool useLengthType, bool addLength>
12401241
static bool __cdecl InitializeFunction(DynamicObject* function, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode);
12411242
virtual void Finalize(bool isShutdown) override;
12421243

test/Bugs/randombug.baseline

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ undefined
111111
25
112112
Passed
113113
Test case 46
114-
name,length
114+
length,name
115115
Passed
116116
Test case 47
117117
\n in label accepted

test/DebuggerCommon/ES6_intl_simple_attach.js.dbg.baseline

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@
132132
"resolvedOptions": "function <large string>",
133133
"compare": "function <large string>"
134134
},
135+
"length": "number 0",
135136
"name": "string Collator",
136137
"supportedLocalesOf": {
137138
"#__proto__": "function <large string>",
138-
"name": "string <large string>",
139-
"length": "number 1"
140-
},
141-
"length": "number 0"
139+
"length": "number 1",
140+
"name": "string <large string>"
141+
}
142142
},
143143
"resolvedOptions": {
144144
"#__proto__": {
@@ -154,8 +154,8 @@
154154
"caller": "Error <large string>",
155155
"arguments": "Error <large string>"
156156
},
157-
"name": "string resolvedOptions",
158-
"length": "number 0"
157+
"length": "number 0",
158+
"name": "string resolvedOptions"
159159
},
160160
"compare": {
161161
"#__proto__": {
@@ -171,7 +171,8 @@
171171
"caller": "Error <large string>",
172172
"arguments": "Error <large string>"
173173
},
174-
"length": "number 2"
174+
"length": "number 2",
175+
"name": "string "
175176
}
176177
}
177178
}
@@ -281,13 +282,13 @@
281282
"resolvedOptions": "function <large string>",
282283
"format": "function <large string>"
283284
},
285+
"length": "number 0",
284286
"name": "string NumberFormat",
285287
"supportedLocalesOf": {
286288
"#__proto__": "function <large string>",
287-
"name": "string <large string>",
288-
"length": "number 1"
289-
},
290-
"length": "number 0"
289+
"length": "number 1",
290+
"name": "string <large string>"
291+
}
291292
},
292293
"resolvedOptions": {
293294
"#__proto__": {
@@ -303,8 +304,8 @@
303304
"caller": "Error <large string>",
304305
"arguments": "Error <large string>"
305306
},
306-
"name": "string resolvedOptions",
307-
"length": "number 0"
307+
"length": "number 0",
308+
"name": "string resolvedOptions"
308309
},
309310
"format": {
310311
"#__proto__": {
@@ -320,7 +321,8 @@
320321
"caller": "Error <large string>",
321322
"arguments": "Error <large string>"
322323
},
323-
"length": "number 1"
324+
"length": "number 1",
325+
"name": "string "
324326
}
325327
}
326328
}
@@ -430,6 +432,7 @@
430432
"format": "function <large string>",
431433
"resolvedOptions": "function <large string>"
432434
},
435+
"length": "number 0",
433436
"name": "string DateTimeFormat",
434437
"__relevantExtensionKeys": {
435438
"#__proto__": "Array []",
@@ -439,10 +442,9 @@
439442
},
440443
"supportedLocalesOf": {
441444
"#__proto__": "function <large string>",
442-
"name": "string <large string>",
443-
"length": "number 1"
444-
},
445-
"length": "number 0"
445+
"length": "number 1",
446+
"name": "string <large string>"
447+
}
446448
},
447449
"format": {
448450
"#__proto__": {
@@ -458,7 +460,8 @@
458460
"caller": "Error <large string>",
459461
"arguments": "Error <large string>"
460462
},
461-
"length": "number 1"
463+
"length": "number 1",
464+
"name": "string "
462465
},
463466
"resolvedOptions": {
464467
"#__proto__": {
@@ -474,8 +477,8 @@
474477
"caller": "Error <large string>",
475478
"arguments": "Error <large string>"
476479
},
477-
"name": "string resolvedOptions",
478-
"length": "number 0"
480+
"length": "number 0",
481+
"name": "string resolvedOptions"
479482
}
480483
}
481484
}

0 commit comments

Comments
 (0)