Files
sdk/runtime/vm/bitmap.cc
T
turnidge@google.com 2803d78dfd Change the zone allocation api.
Instead of passing a size in bytes to the allocation function, we now
have a templatized Alloc function:

  zone->Alloc<Type>(len)

This is better for security, as we can check for integer overflow in
the size computation before performing the allocation.  Before, we
often failed to check this.
Review URL: https://chromiumcodereview.appspot.com//10836061

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@10254 260f80e4-7a28-3924-810f-c04153c831b5
2012-08-03 21:51:44 +00:00

110 lines
2.8 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/object.h"
namespace dart {
bool BitmapBuilder::Get(intptr_t bit_offset) const {
if (!InRange(bit_offset)) {
return false;
}
return GetBit(bit_offset);
}
void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
while (!InRange(bit_offset)) {
intptr_t new_size = size_in_bytes_ + kIncrementSizeInBytes;
ASSERT(new_size > 0);
uint8_t* new_bit_list =
Isolate::Current()->current_zone()->Alloc<uint8_t>(new_size);
ASSERT(new_bit_list != NULL);
ASSERT(bit_list_ != NULL);
uint8_t* old_bit_list = bit_list_;
memmove(new_bit_list, old_bit_list, size_in_bytes_);
memset((new_bit_list + size_in_bytes_), 0, kIncrementSizeInBytes);
size_in_bytes_ = new_size;
bit_list_ = new_bit_list;
}
SetBit(bit_offset, value);
}
// Return the bit offset of the highest bit set.
intptr_t BitmapBuilder::Maximum() const {
intptr_t bound = SizeInBits();
for (intptr_t i = (bound - 1); i >= 0; i--) {
if (Get(i)) return i;
}
return Stackmap::kNoMaximum;
}
// Return the bit offset of the lowest bit set.
intptr_t BitmapBuilder::Minimum() const {
intptr_t bound = SizeInBits();
for (intptr_t i = 0; i < bound; i++) {
if (Get(i)) return i;
}
return Stackmap::kNoMinimum;
}
void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) {
for (intptr_t i = min; i <= max; i++) {
Set(i, value);
}
}
void BitmapBuilder::SetBits(const Stackmap& stackmap) {
intptr_t min = stackmap.MinimumBitIndex();
intptr_t max = stackmap.MaximumBitIndex();
if (min == Stackmap::kNoMinimum || max == Stackmap::kNoMaximum) {
return;
}
for (intptr_t i = 0; i < min; i++) {
Set(i, false);
}
for (intptr_t i = min; i <= max; i++) {
Set(i, stackmap.IsObject(i));
}
intptr_t bound = SizeInBits();
for (intptr_t i = (max + 1); i < bound; i++) {
Set(i, false);
}
}
bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
ASSERT(InRange(bit_offset));
int byte_offset = bit_offset >> kBitsPerByteLog2;
int bit_remainder = bit_offset & (kBitsPerByte - 1);
uint8_t mask = 1U << bit_remainder;
ASSERT(bit_list_ != NULL);
return ((bit_list_[byte_offset] & mask) != 0);
}
void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
ASSERT(InRange(bit_offset));
int byte_offset = bit_offset >> kBitsPerByteLog2;
int bit_remainder = bit_offset & (kBitsPerByte - 1);
uint8_t mask = 1U << bit_remainder;
uint8_t* byte_addr;
ASSERT(bit_list_ != NULL);
byte_addr = &(bit_list_[byte_offset]);
if (value) {
*byte_addr |= mask;
} else {
*byte_addr &= ~mask;
}
}
} // namespace dart