1 | // Copyright (c) 2012, 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 | #include "vm/bitmap.h" |
6 | |
7 | #include "platform/assert.h" |
8 | #include "vm/code_descriptors.h" |
9 | #include "vm/object.h" |
10 | #include "vm/unit_test.h" |
11 | |
12 | namespace dart { |
13 | |
14 | // 0x4 is just a placeholder PC offset because no entry of a CSM should |
15 | // have a PC offset of 0, otherwise internal assumptions break. |
16 | static const uint32_t kTestPcOffset = 0x4; |
17 | static const intptr_t kTestSpillSlotBitCount = 0; |
18 | |
19 | static CompressedStackMapsPtr MapsFromBuilder(BitmapBuilder* bmap) { |
20 | CompressedStackMapsBuilder builder; |
21 | builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount); |
22 | return builder.Finalize(); |
23 | } |
24 | |
25 | ISOLATE_UNIT_TEST_CASE(BitmapBuilder) { |
26 | // Test basic bit map builder operations. |
27 | BitmapBuilder* builder1 = new BitmapBuilder(); |
28 | EXPECT_EQ(0, builder1->Length()); |
29 | |
30 | bool value = true; |
31 | for (int32_t i = 0; i < 128; i++) { |
32 | builder1->Set(i, value); |
33 | value = !value; |
34 | } |
35 | EXPECT_EQ(128, builder1->Length()); |
36 | value = true; |
37 | for (int32_t i = 0; i < 128; i++) { |
38 | EXPECT_EQ(value, builder1->Get(i)); |
39 | value = !value; |
40 | } |
41 | value = true; |
42 | for (int32_t i = 0; i < 1024; i++) { |
43 | builder1->Set(i, value); |
44 | value = !value; |
45 | } |
46 | EXPECT_EQ(1024, builder1->Length()); |
47 | value = true; |
48 | for (int32_t i = 0; i < 1024; i++) { |
49 | EXPECT_EQ(value, builder1->Get(i)); |
50 | value = !value; |
51 | } |
52 | |
53 | // Create a CompressedStackMaps object and verify its contents. |
54 | const auto& maps1 = CompressedStackMaps::Handle(MapsFromBuilder(builder1)); |
55 | CompressedStackMapsIterator it1(maps1); |
56 | EXPECT(it1.MoveNext()); |
57 | |
58 | EXPECT_EQ(kTestPcOffset, it1.pc_offset()); |
59 | EXPECT_EQ(kTestSpillSlotBitCount, it1.SpillSlotBitCount()); |
60 | EXPECT_EQ(1024, it1.Length()); |
61 | value = true; |
62 | for (int32_t i = 0; i < 1024; i++) { |
63 | EXPECT_EQ(value, it1.IsObject(i)); |
64 | value = !value; |
65 | } |
66 | |
67 | EXPECT(!it1.MoveNext()); |
68 | |
69 | // Test the SetRange function in the builder. |
70 | builder1->SetRange(0, 256, false); |
71 | EXPECT_EQ(1024, builder1->Length()); |
72 | builder1->SetRange(257, 1024, true); |
73 | EXPECT_EQ(1025, builder1->Length()); |
74 | builder1->SetRange(1025, 2048, false); |
75 | EXPECT_EQ(2049, builder1->Length()); |
76 | for (int32_t i = 0; i <= 256; i++) { |
77 | EXPECT(!builder1->Get(i)); |
78 | } |
79 | for (int32_t i = 257; i <= 1024; i++) { |
80 | EXPECT(builder1->Get(i)); |
81 | } |
82 | for (int32_t i = 1025; i <= 2048; i++) { |
83 | EXPECT(!builder1->Get(i)); |
84 | } |
85 | |
86 | const auto& maps2 = CompressedStackMaps::Handle(MapsFromBuilder(builder1)); |
87 | CompressedStackMapsIterator it2(maps2); |
88 | EXPECT(it2.MoveNext()); |
89 | |
90 | EXPECT_EQ(kTestPcOffset, it2.pc_offset()); |
91 | EXPECT_EQ(kTestSpillSlotBitCount, it2.SpillSlotBitCount()); |
92 | EXPECT_EQ(2049, it2.Length()); |
93 | for (int32_t i = 0; i <= 256; i++) { |
94 | EXPECT(!it2.IsObject(i)); |
95 | } |
96 | for (int32_t i = 257; i <= 1024; i++) { |
97 | EXPECT(it2.IsObject(i)); |
98 | } |
99 | for (int32_t i = 1025; i <= 2048; i++) { |
100 | EXPECT(!it2.IsObject(i)); |
101 | } |
102 | |
103 | EXPECT(!it2.MoveNext()); |
104 | |
105 | // Test using SetLength to shorten the builder, followed by lengthening. |
106 | builder1->SetLength(747); |
107 | EXPECT_EQ(747, builder1->Length()); |
108 | for (int32_t i = 257; i < 747; ++i) { |
109 | EXPECT(builder1->Get(i)); |
110 | } |
111 | |
112 | builder1->Set(800, false); |
113 | EXPECT_EQ(801, builder1->Length()); |
114 | for (int32_t i = 257; i < 747; ++i) { |
115 | EXPECT(builder1->Get(i)); |
116 | } |
117 | for (int32_t i = 747; i < 801; ++i) { |
118 | EXPECT(!builder1->Get(i)); |
119 | } |
120 | |
121 | builder1->Set(900, true); |
122 | EXPECT_EQ(901, builder1->Length()); |
123 | for (int32_t i = 257; i < 747; ++i) { |
124 | EXPECT(builder1->Get(i)); |
125 | } |
126 | for (int32_t i = 747; i < 900; ++i) { |
127 | EXPECT(!builder1->Get(i)); |
128 | } |
129 | EXPECT(builder1->Get(900)); |
130 | } |
131 | |
132 | } // namespace dart |
133 | |