Skip to content

Commit a9c56ea

Browse files
committed
Add specialized types of Sets and Maps
1 parent 3b3e3f8 commit a9c56ea

15 files changed

+1250
-578
lines changed

lib/Backend/JITRecyclableObject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class JITJavascriptString : JITRecyclableObject
3838
return m_charLength;
3939
}
4040

41-
static bool Equals(Js::Var aLeft, Js::Var aRight)
41+
static bool Equals(JITJavascriptString* aLeft, JITJavascriptString* aRight)
4242
{
4343
return Js::JavascriptStringHelpers<JITJavascriptString>::Equals(aLeft, aRight);
4444
}

lib/Runtime/Language/JavascriptConversion.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,19 @@ namespace Js
5555
template<bool zero>
5656
bool JavascriptConversion::SameValueCommon(Var aLeft, Var aRight)
5757
{
58+
if (aLeft == aRight)
59+
{
60+
return true;
61+
}
62+
5863
TypeId leftType = JavascriptOperators::GetTypeId(aLeft);
59-
TypeId rightType = JavascriptOperators::GetTypeId(aRight);
6064

6165
if (JavascriptOperators::IsUndefinedOrNullType(leftType))
6266
{
63-
return leftType == rightType;
67+
return false;
6468
}
6569

70+
TypeId rightType = JavascriptOperators::GetTypeId(aRight);
6671
double dblLeft, dblRight;
6772

6873
switch (leftType)
@@ -71,7 +76,7 @@ namespace Js
7176
switch (rightType)
7277
{
7378
case TypeIds_Integer:
74-
return aLeft == aRight;
79+
return false;
7580
case TypeIds_Number:
7681
dblLeft = TaggedInt::ToDouble(aLeft);
7782
dblRight = JavascriptNumber::GetValue(aRight);
@@ -182,17 +187,12 @@ namespace Js
182187
}
183188
break;
184189
case TypeIds_Boolean:
185-
switch (rightType)
186-
{
187-
case TypeIds_Boolean:
188-
return aLeft == aRight;
189-
}
190-
break;
190+
return false;
191191
case TypeIds_String:
192192
switch (rightType)
193193
{
194194
case TypeIds_String:
195-
return JavascriptString::Equals(aLeft, aRight);
195+
return JavascriptString::Equals(JavascriptString::UnsafeFromVar(aLeft), JavascriptString::UnsafeFromVar(aRight));
196196
}
197197
break;
198198
case TypeIds_Symbol:
@@ -209,7 +209,7 @@ namespace Js
209209
default:
210210
break;
211211
}
212-
return aLeft == aRight;
212+
return false;
213213
}
214214

215215
template bool JavascriptConversion::SameValueCommon<false>(Var aLeft, Var aRight);
@@ -1656,4 +1656,37 @@ namespace Js
16561656

16571657
return NumberUtilities::TryToInt64(length);
16581658
}
1659+
1660+
Var JavascriptConversion::TryCanonicalizeAsSimpleVar(Var value)
1661+
{
1662+
TypeId typeId = JavascriptOperators::GetTypeId(value);
1663+
switch (typeId)
1664+
{
1665+
case TypeIds_Integer:
1666+
case TypeIds_Number:
1667+
{
1668+
Var taggedInt = TryCanonicalizeAsTaggedInt<true>(value);
1669+
if (taggedInt)
1670+
{
1671+
return taggedInt;
1672+
}
1673+
1674+
#if FLOATVAR
1675+
return value;
1676+
#else
1677+
return nullptr;
1678+
#endif
1679+
}
1680+
case TypeIds_String:
1681+
case TypeIds_Symbol:
1682+
// TODO: try to canonicalize Int64/Uint64 to TaggedInt
1683+
case TypeIds_Int64Number:
1684+
case TypeIds_UInt64Number:
1685+
return nullptr;
1686+
1687+
default:
1688+
return value;
1689+
}
1690+
}
1691+
16591692
} // namespace Js

lib/Runtime/Language/JavascriptConversion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ namespace Js {
8989
static double LongToDouble(__int64 aValue);
9090
static double ULongToDouble(unsigned __int64 aValue);
9191

92+
template <bool allowNegOne>
93+
static Var TryCanonicalizeAsTaggedInt(Var value);
94+
static Var TryCanonicalizeAsSimpleVar(Var value);
95+
9296
private:
9397
static BOOL ToInt32Finite(double value, int32* result);
9498
template<bool zero>

lib/Runtime/Language/JavascriptConversion.inl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,40 @@ namespace Js {
203203
return SameValueCommon<true>(aValue, bValue);
204204
}
205205

206+
template <bool allowNegOne>
207+
inline Var JavascriptConversion::TryCanonicalizeAsTaggedInt(Var value)
208+
{
209+
if (TaggedInt::Is(value))
210+
{
211+
return (allowNegOne || value != TaggedInt::ToVarUnchecked(-1))
212+
? value
213+
: nullptr;
214+
}
215+
216+
if (!JavascriptNumber::Is(value))
217+
{
218+
return nullptr;
219+
}
220+
221+
double doubleVal = JavascriptNumber::GetValue(value);
222+
int32 intVal = 0;
223+
224+
if (!JavascriptNumber::TryGetInt32Value<true>(doubleVal, &intVal))
225+
{
226+
return nullptr;
227+
}
228+
229+
if (TaggedInt::IsOverflow(intVal))
230+
{
231+
return false;
232+
}
233+
234+
if (!allowNegOne && intVal == -1)
235+
{
236+
return false;
237+
}
238+
239+
return TaggedInt::ToVarUnchecked(intVal);
240+
}
241+
206242
} // namespace Js

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -862,14 +862,14 @@ namespace Js
862862
}
863863
#endif
864864

865-
BOOL JavascriptOperators::StrictEqualString(Var aLeft, Var aRight)
865+
BOOL JavascriptOperators::StrictEqualString(Var aLeft, JavascriptString* aRight)
866866
{
867-
Assert(JavascriptOperators::GetTypeId(aRight) == TypeIds_String);
868-
869-
if (JavascriptOperators::GetTypeId(aLeft) != TypeIds_String)
867+
JavascriptString* leftStr = TryFromVar<JavascriptString>(aLeft);
868+
if (!leftStr)
869+
{
870870
return false;
871-
872-
return JavascriptString::Equals(aLeft, aRight);
871+
}
872+
return JavascriptString::Equals(leftStr, aRight);
873873
}
874874

875875
BOOL JavascriptOperators::StrictEqualEmptyString(Var aLeft)
@@ -901,7 +901,7 @@ namespace Js
901901
switch (rightType)
902902
{
903903
case TypeIds_String:
904-
return JavascriptString::Equals(aLeft, aRight);
904+
return JavascriptString::Equals(JavascriptString::UnsafeFromVar(aLeft), JavascriptString::UnsafeFromVar(aRight));
905905
}
906906
return FALSE;
907907
case TypeIds_Integer:
@@ -5298,7 +5298,7 @@ namespace Js
52985298
return JavascriptBoolean::ToVar(JavascriptOperators::StrictEqual(a, b, scriptContext), scriptContext);
52995299
}
53005300

5301-
Var JavascriptOperators::OP_CmSrEq_String(Var a, Var b, ScriptContext *scriptContext)
5301+
Var JavascriptOperators::OP_CmSrEq_String(Var a, JavascriptString* b, ScriptContext *scriptContext)
53025302
{
53035303
return JavascriptBoolean::ToVar(JavascriptOperators::StrictEqualString(a, b), scriptContext);
53045304
}

lib/Runtime/Language/JavascriptOperators.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ namespace Js
150150
static BOOL LessEqual(Var aLeft, Var aRight,ScriptContext* scriptContext);
151151
static BOOL NotEqual(Var aLeft, Var aRight,ScriptContext* scriptContext);
152152
static BOOL StrictEqual(Var aLeft, Var aRight,ScriptContext* scriptContext);
153-
static BOOL StrictEqualString(Var aLeft, Var aRight);
153+
static BOOL StrictEqualString(Var aLeft, JavascriptString* aRight);
154154
static BOOL StrictEqualEmptyString(Var aLeft);
155155
static BOOL StrictEqualSIMD(Var aLeft, Var aRight, ScriptContext* scriptContext);
156156
static BOOL NotStrictEqual(Var aLeft, Var aRight,ScriptContext* scriptContext);
@@ -401,7 +401,7 @@ namespace Js
401401
static Var OP_CmEq_A(Js::Var a,Js::Var b,ScriptContext* scriptContext);
402402
static Var OP_CmNeq_A(Js::Var a,Js::Var b,ScriptContext* scriptContext);
403403
static Var OP_CmSrEq_A(Js::Var a,Js::Var b,ScriptContext* scriptContext);
404-
static Var OP_CmSrEq_String(Var a, Var b, ScriptContext *scriptContext);
404+
static Var OP_CmSrEq_String(Var a, JavascriptString* b, ScriptContext *scriptContext);
405405
static Var OP_CmSrEq_EmptyString(Var a, ScriptContext *scriptContext);
406406
static Var OP_CmSrNeq_A(Js::Var a,Js::Var b,ScriptContext* scriptContext);
407407
static Var OP_CmLt_A(Js::Var a,Js::Var b,ScriptContext* scriptContext);

lib/Runtime/Library/JavascriptLibrary.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6288,7 +6288,7 @@ namespace Js
62886288
AssertOrFailFast(hasRight);
62896289

62906290
// If the strings at this index are not equal, the callsite objects are not equal.
6291-
if (!Js::JavascriptString::Equals(varLeft, varRight))
6291+
if (!Js::JavascriptString::Equals(JavascriptString::FromVar(varLeft), JavascriptString::FromVar(varRight)))
62926292
{
62936293
return false;
62946294
}

0 commit comments

Comments
 (0)