Files
sdk/runtime/vm/bitmap_test.cc
T
Teagan Strickland c9f6e669f9 [vm/compiler] Reland "Further compress the information... in StackMaps."
Fixes an assumption that CompressedStackMapsIterator::Find() is never
passed a PC offset of 0. Adds back an ASSERT that was dropped which checks
for specific cases where a given PC offset does not have a stack map entry.

Original commit message:

Lifting the PC offset in a2bb730 was a small, lightweight change that
gave us big gains, at least on 32-bit architectures. Here, we make
much more invasive changes that will improve the amount of memory used
by the information previously stored in StackMap objects.

Instead of allocating separate objects for StackMaps, we instead compress
all StackMap information for a given Code object into a single object
(CompressedStackMaps, or CSM for short). This replaces the Array used to
store PC offsets (as Smis) and the individual StackMap objects.

While we lose all canonicalization for individual StackMap entries, the
drop in space required to store stack map information more than offsets that.

-----

The impact on AOT snapshot size when compiling the Flutter Gallery
in release mode:

   armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%)
   armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%)

The impact on in-memory, not on-disk, size for the Flutter Gallery as seen
in the Observatory while running a profile (not release) build:

   armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB)
   armv8: Drops from 13.5MB to 11.7MB (-1.8 MB)

-----

Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try
Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00

133 lines
3.7 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/bitmap.h"
#include "platform/assert.h"
#include "vm/code_descriptors.h"
#include "vm/object.h"
#include "vm/unit_test.h"
namespace dart {
// 0x4 is just a placeholder PC offset because no entry of a CSM should
// have a PC offset of 0, otherwise internal assumptions break.
static const uint32_t kTestPcOffset = 0x4;
static const intptr_t kTestSpillSlotBitCount = 0;
static RawCompressedStackMaps* MapsFromBuilder(BitmapBuilder* bmap) {
CompressedStackMapsBuilder builder;
builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount);
return builder.Finalize();
}
ISOLATE_UNIT_TEST_CASE(BitmapBuilder) {
// Test basic bit map builder operations.
BitmapBuilder* builder1 = new BitmapBuilder();
EXPECT_EQ(0, builder1->Length());
bool value = true;
for (int32_t i = 0; i < 128; i++) {
builder1->Set(i, value);
value = !value;
}
EXPECT_EQ(128, builder1->Length());
value = true;
for (int32_t i = 0; i < 128; i++) {
EXPECT_EQ(value, builder1->Get(i));
value = !value;
}
value = true;
for (int32_t i = 0; i < 1024; i++) {
builder1->Set(i, value);
value = !value;
}
EXPECT_EQ(1024, builder1->Length());
value = true;
for (int32_t i = 0; i < 1024; i++) {
EXPECT_EQ(value, builder1->Get(i));
value = !value;
}
// Create a CompressedStackMaps object and verify its contents.
const auto& maps1 = CompressedStackMaps::Handle(MapsFromBuilder(builder1));
CompressedStackMapsIterator it1(maps1);
EXPECT(it1.MoveNext());
EXPECT_EQ(kTestPcOffset, it1.pc_offset());
EXPECT_EQ(kTestSpillSlotBitCount, it1.spill_slot_bit_count());
EXPECT_EQ(1024, it1.length());
value = true;
for (int32_t i = 0; i < 1024; i++) {
EXPECT_EQ(value, it1.IsObject(i));
value = !value;
}
EXPECT(!it1.MoveNext());
// Test the SetRange function in the builder.
builder1->SetRange(0, 256, false);
EXPECT_EQ(1024, builder1->Length());
builder1->SetRange(257, 1024, true);
EXPECT_EQ(1025, builder1->Length());
builder1->SetRange(1025, 2048, false);
EXPECT_EQ(2049, builder1->Length());
for (int32_t i = 0; i <= 256; i++) {
EXPECT(!builder1->Get(i));
}
for (int32_t i = 257; i <= 1024; i++) {
EXPECT(builder1->Get(i));
}
for (int32_t i = 1025; i <= 2048; i++) {
EXPECT(!builder1->Get(i));
}
const auto& maps2 = CompressedStackMaps::Handle(MapsFromBuilder(builder1));
CompressedStackMapsIterator it2(maps2);
EXPECT(it2.MoveNext());
EXPECT_EQ(kTestPcOffset, it2.pc_offset());
EXPECT_EQ(kTestSpillSlotBitCount, it2.spill_slot_bit_count());
EXPECT_EQ(2049, it2.length());
for (int32_t i = 0; i <= 256; i++) {
EXPECT(!it2.IsObject(i));
}
for (int32_t i = 257; i <= 1024; i++) {
EXPECT(it2.IsObject(i));
}
for (int32_t i = 1025; i <= 2048; i++) {
EXPECT(!it2.IsObject(i));
}
EXPECT(!it2.MoveNext());
// Test using SetLength to shorten the builder, followed by lengthening.
builder1->SetLength(747);
EXPECT_EQ(747, builder1->Length());
for (int32_t i = 257; i < 747; ++i) {
EXPECT(builder1->Get(i));
}
builder1->Set(800, false);
EXPECT_EQ(801, builder1->Length());
for (int32_t i = 257; i < 747; ++i) {
EXPECT(builder1->Get(i));
}
for (int32_t i = 747; i < 801; ++i) {
EXPECT(!builder1->Get(i));
}
builder1->Set(900, true);
EXPECT_EQ(901, builder1->Length());
for (int32_t i = 257; i < 747; ++i) {
EXPECT(builder1->Get(i));
}
for (int32_t i = 747; i < 900; ++i) {
EXPECT(!builder1->Get(i));
}
EXPECT(builder1->Get(900));
}
} // namespace dart