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
12namespace 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.
16static const uint32_t kTestPcOffset = 0x4;
17static const intptr_t kTestSpillSlotBitCount = 0;
18
19static CompressedStackMapsPtr MapsFromBuilder(BitmapBuilder* bmap) {
20 CompressedStackMapsBuilder builder;
21 builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount);
22 return builder.Finalize();
23}
24
25ISOLATE_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