Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21446,7 +21446,7 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
case TyInt16:
case TyInt32:
case TyInt64:
_snwprintf_s(constBuf, constBufSize, sizeof(IntConstType) == 8 ? _u("lld%") : _u("%d"), candidate->constant.u.intConst.value);
_snwprintf_s(constBuf, constBufSize, sizeof(IntConstType) == 8 ? _u("%lld") : _u("%d"), candidate->constant.u.intConst.value);
break;
case TyFloat32:
case TyFloat64:
Expand Down
56 changes: 56 additions & 0 deletions lib/Runtime/Library/JavascriptArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3956,6 +3956,62 @@ namespace Js
return -1;
}

template<typename T>
bool AreAllBytesEqual(T value)
{
byte* bValue = (byte*)&value;
byte firstByte = *bValue++;
for (int i = 1; i < sizeof(T); ++i)
{
if (*bValue++ != firstByte)
{
return false;
}
}
return true;
}

template<>
void JavascriptArray::CopyValueToSegmentBuferNoCheck(double* buffer, uint32 length, double value)
{
if (JavascriptNumber::IsZero(value) && !JavascriptNumber::IsNegZero(value))
{
memset(buffer, 0, sizeof(double) * length);
}
else
{
for (uint32 i = 0; i < length; i++)
{
buffer[i] = value;
}
}
}

template<>
void JavascriptArray::CopyValueToSegmentBuferNoCheck(int32* buffer, uint32 length, int32 value)
{
if (value == 0 || AreAllBytesEqual(value))
{
memset(buffer, *(byte*)&value, sizeof(int32)* length);
}
else
{
for (uint32 i = 0; i < length; i++)
{
buffer[i] = value;
}
}
}

template<>
void JavascriptArray::CopyValueToSegmentBuferNoCheck(Js::Var* buffer, uint32 length, Js::Var value)
{
for (uint32 i = 0; i < length; i++)
{
buffer[i] = value;
}
}

int32 JavascriptNativeIntArray::HeadSegmentIndexOfHelper(Var search, uint32 &fromIndex, uint32 toIndex, bool includesAlgorithm, ScriptContext * scriptContext)
{
// We proceed largely in the same manner as in JavascriptArray's version of this method (see comments there for more information),
Expand Down
1 change: 1 addition & 0 deletions lib/Runtime/Library/JavascriptArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ namespace Js
#if ENABLE_PROFILE_INFO
template<typename T> inline void DirectProfiledSetItemInHeadSegmentAt(const uint32 offset, const T newValue, StElemInfo *const stElemInfo);
#endif
template<typename T> static void CopyValueToSegmentBuferNoCheck(T* buffer, uint32 length, T value);
template<typename T> void DirectSetItem_Full(uint32 itemIndex, T newValue);
template<typename T> SparseArraySegment<T>* PrepareSegmentForMemOp(uint32 startIndex, uint32 length);
template<typename T> bool DirectSetItemAtRange(uint32 startIndex, uint32 length, T newValue);
Expand Down
40 changes: 6 additions & 34 deletions lib/Runtime/Library/JavascriptArray.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ SECOND_PASS:
#endif
return true;
}

template<typename T>
bool JavascriptArray::DirectSetItemAtRange(uint32 startIndex, uint32 length, T newValue)
{
Expand All @@ -1033,18 +1034,7 @@ SECOND_PASS:

if (startIndex == 0 && head != EmptySegment && length < head->size)
{
if (newValue == (T)0 || newValue == (T)(-1))
{
memset(((Js::SparseArraySegment<T>*)head)->elements, ((int)(intptr_t)newValue), sizeof(T)* length);
}
else
{
Js::SparseArraySegment<T>* headSegment = ((Js::SparseArraySegment<T>*)head);
for (uint32 i = 0; i < length; i++)
{
headSegment->elements[i] = newValue;
}
}
CopyValueToSegmentBuferNoCheck(((Js::SparseArraySegment<T>*)head)->elements, length, newValue);

if (length > this->length)
{
Expand Down Expand Up @@ -1082,17 +1072,7 @@ SECOND_PASS:

SetHasNoMissingValues(true);

if (newValue == (T)0 || newValue == (T)(-1))
{
memset(((Js::SparseArraySegment<T>*)current)->elements, ((int)(intptr_t)newValue), sizeof(T)* length);
}
else
{
for (uint32 i = 0; i < length; i++)
{
((Js::SparseArraySegment<T>*)current)->elements[i] = newValue;
}
}
CopyValueToSegmentBuferNoCheck(((Js::SparseArraySegment<T>*)current)->elements, length, newValue);
this->SetLastUsedSegment(current);
}
else
Expand All @@ -1116,17 +1096,9 @@ SECOND_PASS:
{
return false;
}
if (newValue == (T)0 || newValue == (T)(-1))
{
memset((((Js::SparseArraySegment<T>*)current)->elements + (startIndex - current->left)), ((int)(intptr_t)newValue), sizeof(T)* length);
}
else
{
for (uint32 i = 0; i < length; i++)
{
((Js::SparseArraySegment<T>*)current)->elements[startIndex - current->left + i] = newValue;
}
}
Assert(current->left + current->length >= startIndex + length);
T* segmentCopyStart = current->elements + (startIndex - current->left);
CopyValueToSegmentBuferNoCheck(segmentCopyStart, length, newValue);
this->SetLastUsedSegment(current);
#if DBG
if (Js::Configuration::Global.flags.MemOpMissingValueValidate)
Expand Down