void BreakTarget::CopyTo(BreakTarget* destination) {
ASSERT(destination != NULL);
destination->direction_ = direction_;
- destination->reaching_frames_ = reaching_frames_;
- destination->merge_labels_ = merge_labels_;
+ destination->reaching_frames_.Rewind(0);
+ destination->reaching_frames_.AddAll(reaching_frames_);
+ destination->merge_labels_.Rewind(0);
+ destination->merge_labels_.AddAll(merge_labels_);
destination->entry_frame_ = entry_frame_;
destination->entry_label_ = entry_label_;
destination->expected_height_ = expected_height_;
template<typename T, class P>
-List<T, P>::List(const List<T, P>& other) {
- ASSERT(other.capacity() >= 0);
- capacity_ = other.capacity();
- length_ = other.length();
- if (capacity_ > 0) {
- data_ = NewData(capacity_);
- int copy_size = length_ * sizeof(T);
- const int kMinMemCpySize = 64;
- if (copy_size < kMinMemCpySize) {
- for (int i = 0; i < length_; i++) data_[i] = other.data_[i];
- } else {
- memcpy(data_, other.data_, copy_size);
- }
+void List<T, P>::Add(const T& element) {
+ if (length_ < capacity_) {
+ data_[length_++] = element;
} else {
- data_ = NULL;
+ List<T, P>::ResizeAdd(element);
}
}
template<typename T, class P>
-void List<T, P>::Add(const T& element) {
- if (length_ < capacity_) {
- data_[length_++] = element;
- } else {
- List<T, P>::ResizeAdd(element);
+void List<T, P>::AddAll(const List<T, P>& other) {
+ int result_length = length_ + other.length_;
+ if (capacity_ < result_length) Resize(result_length);
+ for (int i = 0; i < other.length_; i++) {
+ data_[length_ + i] = other.data_[i];
}
+ length_ = result_length;
}
// Grow the list capacity by 50%, but make sure to let it grow
// even when the capacity is zero (possible initial case).
int new_capacity = 1 + capacity_ + (capacity_ >> 1);
+ // Since the element reference could be an element of the list, copy
+ // it out of the old backing storage before resizing.
+ T temp = element;
+ Resize(new_capacity);
+ data_[length_++] = temp;
+}
+
+
+template<typename T, class P>
+void List<T, P>::Resize(int new_capacity) {
T* new_data = List<T, P>::NewData(new_capacity);
memcpy(new_data, data_, capacity_ * sizeof(T));
- // Since the element reference could be an element of the list,
- // assign it to the new backing store before deleting the old.
- new_data[length_++] = element;
List<T, P>::DeleteData(data_);
data_ = new_data;
capacity_ = new_capacity;
public:
INLINE(explicit List(int capacity)) { Initialize(capacity); }
- INLINE(explicit List(const List<T, P>& other));
INLINE(~List()) { DeleteData(data_); }
INLINE(void* operator new(size_t size)) { return P::New(size); }
// expanding the list if necessary.
void Add(const T& element);
+ // Add all the elements from the argument list to this list.
+ void AddAll(const List<T, P>& other);
+
// Added 'count' elements with the value 'value' and returns a
// vector that allows access to the elements. The vector is valid
// until the next change is made to this list.
// Inlined implementation of ResizeAdd, shared by inlined and
// non-inlined versions of ResizeAdd.
void ResizeAddInternal(const T& element);
+
+ // Resize the list.
+ void Resize(int new_capacity);
+
+ DISALLOW_COPY_AND_ASSIGN(List);
};
class FrameElement;
// When cloned, a frame is a deep copy of the original.
VirtualFrame::VirtualFrame(VirtualFrame* original)
- : elements_(original->elements_),
+ : elements_(original->elements_.length()),
stack_pointer_(original->stack_pointer_) {
+ elements_.AddAll(original->elements_);
// Copy register locations from original.
memcpy(®ister_locations_,
original->register_locations_,
list.Add(list[0]);
CHECK_EQ(1, list[4]);
}
+
+// Test that we can add all elements from a list to another list.
+TEST(ListAddAll) {
+ List<int, ZeroingAllocationPolicy> list(4);
+ list.Add(0);
+ list.Add(1);
+ list.Add(2);
+
+ CHECK_EQ(3, list.length());
+ for (int i = 0; i < 3; i++) {
+ CHECK_EQ(i, list[i]);
+ }
+
+ List<int, ZeroingAllocationPolicy> other_list(4);
+
+ // Add no elements to list since other_list is empty.
+ list.AddAll(other_list);
+ CHECK_EQ(3, list.length());
+ for (int i = 0; i < 3; i++) {
+ CHECK_EQ(i, list[i]);
+ }
+
+ // Add three elements to other_list.
+ other_list.Add(0);
+ other_list.Add(1);
+ other_list.Add(2);
+
+ // Copy the three elements from other_list to list.
+ list.AddAll(other_list);
+ CHECK_EQ(6, list.length());
+ for (int i = 0; i < 6; i++) {
+ CHECK_EQ(i % 3, list[i]);
+ }
+}