Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Base64 encoding with simd-support #34529

Merged
merged 23 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
daddd95
Optimized scalar code-path
gfoidl Jan 7, 2019
144c431
Fixed label names
gfoidl Jan 10, 2019
81a3c15
Implemented vectorized versions
gfoidl Jan 10, 2019
a46b9b2
Added reference to source of algorithm
gfoidl Jan 10, 2019
2ac8aa4
Added back missing namespace
gfoidl Jan 10, 2019
40d216b
Unsafe.Add instead of Unsafe.Subtract
gfoidl Jan 10, 2019
e7f00fb
Added THIRD-PARTY-NOTICES
gfoidl Jan 11, 2019
6072958
PR Feedback
gfoidl Jan 11, 2019
f2067cc
THIRD-PARTY-NOTICES in repo-base instead instead in folder
gfoidl Jan 11, 2019
6954802
PR Feedback
gfoidl Jan 11, 2019
74e36e7
Rewritten to use raw-pointers instead of GC-tracked refs
gfoidl Jan 13, 2019
294ecaa
Initialized the static fields directly (i.e. w/o cctor)
gfoidl Jan 15, 2019
3016983
Added a test for decoding a (encoded) Guid
gfoidl Jan 16, 2019
0343eda
EncodingMap / DecodingMap as byref instead of pointer
gfoidl Jan 16, 2019
a246816
PR Feedback
gfoidl Mar 5, 2019
d31b7e8
Debug.Fail instead throwing for the assertion
gfoidl Mar 10, 2019
5c0dbee
ROSpan for static data
gfoidl Mar 11, 2019
31c4741
ROS for lookup maps
gfoidl Mar 11, 2019
c8b6cb3
In decode avoided stack spill and hoisted zero-vector outside the loops
gfoidl May 26, 2019
d89692f
Assert assumption about destLength
gfoidl May 26, 2019
c8ee0a9
Added comments from original source and some changes to variable names
gfoidl May 26, 2019
8c53689
Use TestZ instead of MoveMask in AVX2-path
gfoidl May 27, 2019
cf4f5ce
Fixed too complicated mask2F creation
gfoidl May 27, 2019
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
32 changes: 32 additions & 0 deletions THIRD-PARTY-NOTICES.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,35 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

License notice for vectorized base64 encoding / decoding
--------------------------------------------------------

Copyright (c) 2005-2007, Nick Galbreath
Copyright (c) 2013-2017, Alfred Klomp
Copyright (c) 2015-2017, Wojciech Mula
Copyright (c) 2016-2017, Matthieu Darbois
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 change: 1 addition & 0 deletions src/System.Memory/src/System.Memory.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<Compile Include="System\Buffers\SequenceReader.cs" />
<Compile Include="System\Buffers\SequenceReader.Search.cs" />
<Compile Include="System\Buffers\SequenceReaderExtensions.Binary.cs" />
<Compile Include="System\Buffers\Text\Base64.cs" />
<Compile Include="System\Buffers\Text\Base64Decoder.cs" />
<Compile Include="System\Buffers\Text\Base64Encoder.cs" />
<Compile Include="System\Runtime\InteropServices\SequenceMarshal.cs" />
Expand Down
48 changes: 48 additions & 0 deletions src/System.Memory/src/System/Buffers/Text/Base64.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Internal.Runtime.CompilerServices;

namespace System.Buffers.Text
{
public static partial class Base64
{
private static TVector ReadVector<TVector>(ReadOnlySpan<sbyte> data)
gfoidl marked this conversation as resolved.
Show resolved Hide resolved
{
ref sbyte tmp = ref MemoryMarshal.GetReference(data);
return Unsafe.As<sbyte, TVector>(ref tmp);
}

[Conditional("DEBUG")]
private static unsafe void AssertRead<TVector>(byte* src, byte* srcStart, int srcLength)
{
int vectorElements = Unsafe.SizeOf<TVector>();
byte* readEnd = src + vectorElements;
byte* srcEnd = srcStart + srcLength;

if (readEnd > srcEnd)
{
int srcIndex = (int)(src - srcStart);
Debug.Fail($"Read for {typeof(TVector)} is not within safe bounds. srcIndex: {srcIndex}, srcLength: {srcLength}");
}
}

[Conditional("DEBUG")]
private static unsafe void AssertWrite<TVector>(byte* dest, byte* destStart, int destLength)
{
int vectorElements = Unsafe.SizeOf<TVector>();
byte* writeEnd = dest + vectorElements;
byte* destEnd = destStart + destLength;

if (writeEnd > destEnd)
{
int destIndex = (int)(dest - destStart);
Debug.Fail($"Write for {typeof(TVector)} is not within safe bounds. destIndex: {destIndex}, destLength: {destLength}");
}
}
}
}
Loading