Skip to content

Commit d9bb68f

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Fix serialization of SIMD vectors.
Broken by bbefc05. TEST=ci Bug: #46793 Change-Id: I8e5869caee2d705cecaf974cca3ee3f0c542ad3c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/208840 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Siva Annamalai <[email protected]>
1 parent b820538 commit d9bb68f

File tree

6 files changed

+168
-5
lines changed

6 files changed

+168
-5
lines changed

runtime/vm/datastream.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ReadStream : public ValueObject {
8585
};
8686

8787
// Reads 'len' bytes from the stream.
88-
void ReadBytes(uint8_t* addr, intptr_t len) {
88+
void ReadBytes(void* addr, intptr_t len) {
8989
ASSERT((end_ - current_) >= len);
9090
if (len != 0) {
9191
memmove(addr, current_, len);

runtime/vm/message_snapshot.cc

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class BaseSerializer : public StackResource {
145145
void WriteWordWith32BitWrites(uword value) {
146146
stream_.WriteWordWith32BitWrites(value);
147147
}
148-
void WriteBytes(const uint8_t* addr, intptr_t len) {
148+
void WriteBytes(const void* addr, intptr_t len) {
149149
stream_.WriteBytes(addr, len);
150150
}
151151
void WriteAscii(const String& str) {
@@ -344,7 +344,7 @@ class BaseDeserializer : public ValueObject {
344344
}
345345
intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
346346
uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
347-
void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
347+
void ReadBytes(void* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
348348
const char* ReadAscii() {
349349
intptr_t len = ReadUnsigned();
350350
const char* result = reinterpret_cast<const char*>(CurrentBufferAddress());
@@ -1572,8 +1572,7 @@ class TypedDataMessageDeserializationCluster
15721572
d->AssignRef(data.ptr());
15731573
const intptr_t length_in_bytes = length * element_size;
15741574
NoSafepointScope no_safepoint;
1575-
uint8_t* cdata = reinterpret_cast<uint8_t*>(data.untag()->data());
1576-
d->ReadBytes(cdata, length_in_bytes);
1575+
d->ReadBytes(data.untag()->data(), length_in_bytes);
15771576
}
15781577
}
15791578

@@ -2066,6 +2065,60 @@ class TransferableTypedDataMessageDeserializationCluster
20662065
}
20672066
};
20682067

2068+
class Simd128MessageSerializationCluster : public MessageSerializationCluster {
2069+
public:
2070+
explicit Simd128MessageSerializationCluster(intptr_t cid)
2071+
: MessageSerializationCluster("Simd128",
2072+
MessagePhase::kBeforeTypes,
2073+
cid) {}
2074+
~Simd128MessageSerializationCluster() {}
2075+
2076+
void Trace(MessageSerializer* s, Object* object) { objects_.Add(object); }
2077+
2078+
void WriteNodes(MessageSerializer* s) {
2079+
intptr_t count = objects_.length();
2080+
s->WriteUnsigned(count);
2081+
for (intptr_t i = 0; i < count; i++) {
2082+
Object* vector = objects_[i];
2083+
s->AssignRef(vector);
2084+
ASSERT_EQUAL(Int32x4::value_offset(), Float32x4::value_offset());
2085+
ASSERT_EQUAL(Int32x4::value_offset(), Float64x2::value_offset());
2086+
s->WriteBytes(&(static_cast<Int32x4Ptr>(vector->ptr())->untag()->value_),
2087+
sizeof(simd128_value_t));
2088+
}
2089+
}
2090+
2091+
private:
2092+
GrowableArray<Object*> objects_;
2093+
};
2094+
2095+
class Simd128MessageDeserializationCluster
2096+
: public MessageDeserializationCluster {
2097+
public:
2098+
explicit Simd128MessageDeserializationCluster(intptr_t cid)
2099+
: MessageDeserializationCluster("Simd128"), cid_(cid) {}
2100+
~Simd128MessageDeserializationCluster() {}
2101+
2102+
void ReadNodes(MessageDeserializer* d) {
2103+
intptr_t count = d->ReadUnsigned();
2104+
for (intptr_t i = 0; i < count; i++) {
2105+
ASSERT_EQUAL(Int32x4::InstanceSize(), Float32x4::InstanceSize());
2106+
ASSERT_EQUAL(Int32x4::InstanceSize(), Float64x2::InstanceSize());
2107+
ObjectPtr vector =
2108+
Object::Allocate(cid_, Int32x4::InstanceSize(), Heap::kNew,
2109+
Int32x4::ContainsCompressedPointers());
2110+
d->AssignRef(vector);
2111+
ASSERT_EQUAL(Int32x4::value_offset(), Float32x4::value_offset());
2112+
ASSERT_EQUAL(Int32x4::value_offset(), Float64x2::value_offset());
2113+
d->ReadBytes(&(static_cast<Int32x4Ptr>(vector)->untag()->value_),
2114+
sizeof(simd128_value_t));
2115+
}
2116+
}
2117+
2118+
private:
2119+
const intptr_t cid_;
2120+
};
2121+
20692122
class RegExpMessageSerializationCluster : public MessageSerializationCluster {
20702123
public:
20712124
RegExpMessageSerializationCluster()
@@ -3233,6 +3286,10 @@ MessageSerializationCluster* BaseSerializer::NewClusterForClass(
32333286
return new (Z) OneByteStringMessageSerializationCluster(Z, is_canonical);
32343287
case kTwoByteStringCid:
32353288
return new (Z) TwoByteStringMessageSerializationCluster(Z, is_canonical);
3289+
case kInt32x4Cid:
3290+
case kFloat32x4Cid:
3291+
case kFloat64x2Cid:
3292+
return new (Z) Simd128MessageSerializationCluster(cid);
32363293
default:
32373294
break;
32383295
}
@@ -3321,6 +3378,11 @@ MessageDeserializationCluster* BaseDeserializer::ReadCluster() {
33213378
return new (Z) OneByteStringMessageDeserializationCluster(is_canonical);
33223379
case kTwoByteStringCid:
33233380
return new (Z) TwoByteStringMessageDeserializationCluster(is_canonical);
3381+
case kInt32x4Cid:
3382+
case kFloat32x4Cid:
3383+
case kFloat64x2Cid:
3384+
ASSERT(!is_canonical);
3385+
return new (Z) Simd128MessageDeserializationCluster(cid);
33243386
default:
33253387
break;
33263388
}

runtime/vm/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ class Object {
859859
friend void UntaggedObject::Validate(IsolateGroup* isolate_group) const;
860860
friend class Closure;
861861
friend class InstanceDeserializationCluster;
862+
friend class Simd128MessageDeserializationCluster;
862863
friend class OneByteString;
863864
friend class TwoByteString;
864865
friend class ExternalOneByteString;

runtime/vm/raw_object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,6 +3024,8 @@ class UntaggedInt32x4 : public UntaggedInstance {
30243024

30253025
ALIGN8 int32_t value_[4];
30263026

3027+
friend class Simd128MessageSerializationCluster;
3028+
friend class Simd128MessageDeserializationCluster;
30273029

30283030
public:
30293031
int32_t x() const { return value_[0]; }
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// See https://github.com/dart-lang/sdk/issues/46793
6+
7+
import "dart:async";
8+
import "dart:isolate";
9+
import "dart:typed_data";
10+
11+
import "package:async_helper/async_helper.dart";
12+
import "package:expect/expect.dart";
13+
14+
main() {
15+
asyncStart();
16+
var port;
17+
port = new RawReceivePort((message) {
18+
print("Receive $message");
19+
20+
var int32x4 = message[0] as Int32x4;
21+
Expect.equals(-1, int32x4.x);
22+
Expect.equals(0, int32x4.y);
23+
Expect.equals(1, int32x4.z);
24+
Expect.equals(2, int32x4.w);
25+
26+
var float32x4 = message[1] as Float32x4;
27+
Expect.equals(-2.5, float32x4.x);
28+
Expect.equals(0.0, float32x4.y);
29+
Expect.equals(1.25, float32x4.z);
30+
Expect.equals(2.125, float32x4.w);
31+
32+
var float64x2 = message[2] as Float64x2;
33+
Expect.equals(16.5, float64x2.x);
34+
Expect.equals(-32.25, float64x2.y);
35+
36+
port.close();
37+
asyncEnd();
38+
});
39+
40+
41+
var list = [
42+
new Int32x4(-1, 0, 1, 2),
43+
new Float32x4(-2.5, 0.0, 1.25, 2.125),
44+
new Float64x2(16.5, -32.25),
45+
];
46+
print("Send $list");
47+
port.sendPort.send(list);
48+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// See https://github.com/dart-lang/sdk/issues/46793
6+
7+
// @dart = 2.9
8+
9+
import "dart:async";
10+
import "dart:isolate";
11+
import "dart:typed_data";
12+
13+
import "package:async_helper/async_helper.dart";
14+
import "package:expect/expect.dart";
15+
16+
main() {
17+
asyncStart();
18+
var port;
19+
port = new RawReceivePort((message) {
20+
print("Receive $message");
21+
22+
var int32x4 = message[0] as Int32x4;
23+
Expect.equals(-1, int32x4.x);
24+
Expect.equals(0, int32x4.y);
25+
Expect.equals(1, int32x4.z);
26+
Expect.equals(2, int32x4.w);
27+
28+
var float32x4 = message[1] as Float32x4;
29+
Expect.equals(-2.5, float32x4.x);
30+
Expect.equals(0.0, float32x4.y);
31+
Expect.equals(1.25, float32x4.z);
32+
Expect.equals(2.125, float32x4.w);
33+
34+
var float64x2 = message[2] as Float64x2;
35+
Expect.equals(16.5, float64x2.x);
36+
Expect.equals(-32.25, float64x2.y);
37+
38+
port.close();
39+
asyncEnd();
40+
});
41+
42+
43+
var list = [
44+
new Int32x4(-1, 0, 1, 2),
45+
new Float32x4(-2.5, 0.0, 1.25, 2.125),
46+
new Float64x2(16.5, -32.25),
47+
];
48+
print("Send $list");
49+
port.sendPort.send(list);
50+
}

0 commit comments

Comments
 (0)