// 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 constexpr uint32_t kTestPcOffset = 0x4;
static constexpr intptr_t kTestSpillSlotBitCount = 0;

static CompressedStackMapsPtr MapsFromBuilder(Zone* zone, BitmapBuilder* bmap) {
  CompressedStackMapsBuilder builder(zone);
  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(
      thread->zone(), MapsFromBuilder(thread->zone(), builder1));
  auto it1 = maps1.iterator(thread);
  EXPECT(it1.MoveNext());

  EXPECT_EQ(kTestPcOffset, it1.pc_offset());
  EXPECT_EQ(kTestSpillSlotBitCount, it1.SpillSlotBitCount());
  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(
      thread->zone(), MapsFromBuilder(thread->zone(), builder1));
  auto it2 = maps2.iterator(thread);
  EXPECT(it2.MoveNext());

  EXPECT_EQ(kTestPcOffset, it2.pc_offset());
  EXPECT_EQ(kTestSpillSlotBitCount, it2.SpillSlotBitCount());
  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));
}

ISOLATE_UNIT_TEST_CASE(BitmapBuilder_Regress44946) {
  BitmapBuilder* builder1 = new BitmapBuilder();
  EXPECT_EQ(0, builder1->Length());

  builder1->Set(10000, false);
  EXPECT_EQ(10001, builder1->Length());
  builder1->Set(9999, true);
  EXPECT(builder1->Get(9999));
}

}  // namespace dart
