// Check if we still have room for another entry given Arm's ldr and vldr
// immediate offset range.
- if (!(is_uint12(ConstantPoolArray::SizeFor(count_of_64bit_,
- count_of_code_ptr_,
- count_of_heap_ptr_,
- count_of_32bit_))) &&
- is_uint10(ConstantPoolArray::SizeFor(count_of_64bit_, 0, 0, 0))) {
+ // TODO(rmcilroy): Avoid creating a new object here when we support
+ // extended constant pools.
+ ConstantPoolArray::NumberOfEntries total(count_of_64bit_,
+ count_of_code_ptr_,
+ count_of_heap_ptr_,
+ count_of_32bit_);
+ ConstantPoolArray::NumberOfEntries int64_counts(count_of_64bit_, 0, 0, 0);
+ if (!(is_uint12(ConstantPoolArray::SizeFor(total)) &&
+ is_uint10(ConstantPoolArray::SizeFor(int64_counts)))) {
assm->set_constant_pool_full();
}
}
if (IsEmpty()) {
return isolate->factory()->empty_constant_pool_array();
} else {
- return isolate->factory()->NewConstantPoolArray(count_of_64bit_,
- count_of_code_ptr_,
- count_of_heap_ptr_,
- count_of_32bit_);
+ ConstantPoolArray::NumberOfEntries small(count_of_64bit_,
+ count_of_code_ptr_,
+ count_of_heap_ptr_,
+ count_of_32bit_);
+ return isolate->factory()->NewConstantPoolArray(small);
}
}
void ConstantPoolBuilder::Populate(Assembler* assm,
ConstantPoolArray* constant_pool) {
- ASSERT(constant_pool->count_of_int64_entries() == count_of_64bit_);
- ASSERT(constant_pool->count_of_code_ptr_entries() == count_of_code_ptr_);
- ASSERT(constant_pool->count_of_heap_ptr_entries() == count_of_heap_ptr_);
- ASSERT(constant_pool->count_of_int32_entries() == count_of_32bit_);
+ ConstantPoolArray::LayoutSection section = ConstantPoolArray::SMALL_SECTION;
+ ASSERT(count_of_64bit_ ==
+ constant_pool->number_of_entries(ConstantPoolArray::INT64, section));
+ ASSERT(count_of_code_ptr_ ==
+ constant_pool->number_of_entries(ConstantPoolArray::CODE_PTR, section));
+ ASSERT(count_of_heap_ptr_ ==
+ constant_pool->number_of_entries(ConstantPoolArray::HEAP_PTR, section));
+ ASSERT(count_of_32bit_ ==
+ constant_pool->number_of_entries(ConstantPoolArray::INT32, section));
ASSERT(entries_.size() == merged_indexes_.size());
int index_64bit = 0;
offset = constant_pool->OffsetOfElementAt(index_code_ptr) -
kHeapObjectTag;
constant_pool->set(index_code_ptr++,
- reinterpret_cast<Object *>(rinfo->data()));
+ reinterpret_cast<Address>(rinfo->data()));
} else {
ASSERT(IsHeapPtrEntry(rmode));
offset = constant_pool->OffsetOfElementAt(index_heap_ptr) -
Handle<ConstantPoolArray> Factory::NewConstantPoolArray(
- int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- ASSERT(number_of_int64_entries > 0 || number_of_code_ptr_entries > 0 ||
- number_of_heap_ptr_entries > 0 || number_of_int32_entries > 0);
+ const ConstantPoolArray::NumberOfEntries& small) {
+ ASSERT(small.total_count() > 0);
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateConstantPoolArray(number_of_int64_entries,
- number_of_code_ptr_entries,
- number_of_heap_ptr_entries,
- number_of_int32_entries),
+ isolate()->heap()->AllocateConstantPoolArray(small),
+ ConstantPoolArray);
+}
+
+
+Handle<ConstantPoolArray> Factory::NewExtendedConstantPoolArray(
+ const ConstantPoolArray::NumberOfEntries& small,
+ const ConstantPoolArray::NumberOfEntries& extended) {
+ ASSERT(small.total_count() > 0);
+ ASSERT(extended.total_count() > 0);
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateExtendedConstantPoolArray(small, extended),
ConstantPoolArray);
}
PretenureFlag pretenure = NOT_TENURED);
Handle<ConstantPoolArray> NewConstantPoolArray(
- int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries);
+ const ConstantPoolArray::NumberOfEntries& small);
+
+ Handle<ConstantPoolArray> NewExtendedConstantPoolArray(
+ const ConstantPoolArray::NumberOfEntries& small,
+ const ConstantPoolArray::NumberOfEntries& extended);
Handle<OrderedHashSet> NewOrderedHashSet();
Handle<OrderedHashMap> NewOrderedHashMap();
STATIC_ASSERT((FixedDoubleArray::kHeaderSize &
kDoubleAlignmentMask) == 0); // NOLINT
-STATIC_ASSERT((ConstantPoolArray::kHeaderSize &
+STATIC_ASSERT((ConstantPoolArray::kFirstEntryOffset &
+ kDoubleAlignmentMask) == 0); // NOLINT
+STATIC_ASSERT((ConstantPoolArray::kExtendedFirstOffset &
kDoubleAlignmentMask) == 0); // NOLINT
AllocationResult Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
Map* map) {
- int int64_entries = src->count_of_int64_entries();
- int code_ptr_entries = src->count_of_code_ptr_entries();
- int heap_ptr_entries = src->count_of_heap_ptr_entries();
- int int32_entries = src->count_of_int32_entries();
HeapObject* obj;
- { AllocationResult allocation =
- AllocateConstantPoolArray(int64_entries, code_ptr_entries,
- heap_ptr_entries, int32_entries);
+ if (src->is_extended_layout()) {
+ ConstantPoolArray::NumberOfEntries small(src,
+ ConstantPoolArray::SMALL_SECTION);
+ ConstantPoolArray::NumberOfEntries extended(src,
+ ConstantPoolArray::EXTENDED_SECTION);
+ AllocationResult allocation =
+ AllocateExtendedConstantPoolArray(small, extended);
+ if (!allocation.To(&obj)) return allocation;
+ } else {
+ ConstantPoolArray::NumberOfEntries small(src,
+ ConstantPoolArray::SMALL_SECTION);
+ AllocationResult allocation = AllocateConstantPoolArray(small);
if (!allocation.To(&obj)) return allocation;
}
obj->set_map_no_write_barrier(map);
- int size = ConstantPoolArray::SizeFor(
- int64_entries, code_ptr_entries, heap_ptr_entries, int32_entries);
CopyBlock(
- obj->address() + ConstantPoolArray::kLengthOffset,
- src->address() + ConstantPoolArray::kLengthOffset,
- size - ConstantPoolArray::kLengthOffset);
+ obj->address() + ConstantPoolArray::kFirstEntryOffset,
+ src->address() + ConstantPoolArray::kFirstEntryOffset,
+ src->size() - ConstantPoolArray::kFirstEntryOffset);
return obj;
}
}
-AllocationResult Heap::AllocateConstantPoolArray(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- CHECK(number_of_int64_entries >= 0 &&
- number_of_int64_entries <= ConstantPoolArray::kMaxEntriesPerType &&
- number_of_code_ptr_entries >= 0 &&
- number_of_code_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType &&
- number_of_heap_ptr_entries >= 0 &&
- number_of_heap_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType &&
- number_of_int32_entries >= 0 &&
- number_of_int32_entries <= ConstantPoolArray::kMaxEntriesPerType);
- int size = ConstantPoolArray::SizeFor(number_of_int64_entries,
- number_of_code_ptr_entries,
- number_of_heap_ptr_entries,
- number_of_int32_entries);
+AllocationResult Heap::AllocateConstantPoolArray(
+ const ConstantPoolArray::NumberOfEntries& small) {
+ CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType));
+ int size = ConstantPoolArray::SizeFor(small);
#ifndef V8_HOST_ARCH_64_BIT
size += kPointerSize;
#endif
object->set_map_no_write_barrier(constant_pool_array_map());
ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
- constant_pool->Init(number_of_int64_entries,
- number_of_code_ptr_entries,
- number_of_heap_ptr_entries,
- number_of_int32_entries);
- if (number_of_code_ptr_entries > 0) {
- int offset =
- constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index());
- MemsetPointer(
- reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)),
- isolate()->builtins()->builtin(Builtins::kIllegal)->entry(),
- number_of_code_ptr_entries);
- }
- if (number_of_heap_ptr_entries > 0) {
- int offset =
- constant_pool->OffsetOfElementAt(constant_pool->first_heap_ptr_index());
- MemsetPointer(
- HeapObject::RawField(constant_pool, offset),
- undefined_value(),
- number_of_heap_ptr_entries);
+ constant_pool->Init(small);
+ constant_pool->ClearPtrEntries(isolate());
+ return constant_pool;
+}
+
+
+AllocationResult Heap::AllocateExtendedConstantPoolArray(
+ const ConstantPoolArray::NumberOfEntries& small,
+ const ConstantPoolArray::NumberOfEntries& extended) {
+ CHECK(small.are_in_range(0, ConstantPoolArray::kMaxSmallEntriesPerType));
+ CHECK(extended.are_in_range(0, kMaxInt));
+ int size = ConstantPoolArray::SizeForExtended(small, extended);
+#ifndef V8_HOST_ARCH_64_BIT
+ size += kPointerSize;
+#endif
+ AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
+
+ HeapObject* object;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE);
+ if (!allocation.To(&object)) return allocation;
}
+ object = EnsureDoubleAligned(this, object, size);
+ object->set_map_no_write_barrier(constant_pool_array_map());
+
+ ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
+ constant_pool->InitExtended(small, extended);
+ constant_pool->ClearPtrEntries(isolate());
return constant_pool;
}
AllocationResult Heap::AllocateEmptyConstantPoolArray() {
- int size = ConstantPoolArray::SizeFor(0, 0, 0, 0);
+ ConstantPoolArray::NumberOfEntries small(0, 0, 0, 0);
+ int size = ConstantPoolArray::SizeFor(small);
HeapObject* result;
{ AllocationResult allocation =
AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
if (!allocation.To(&result)) return allocation;
}
result->set_map_no_write_barrier(constant_pool_array_map());
- ConstantPoolArray::cast(result)->Init(0, 0, 0, 0);
+ ConstantPoolArray::cast(result)->Init(small);
return result;
}
ConstantPoolArray* src, Map* map);
MUST_USE_RESULT AllocationResult AllocateConstantPoolArray(
- int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries);
+ const ConstantPoolArray::NumberOfEntries& small);
+
+ MUST_USE_RESULT AllocationResult AllocateExtendedConstantPoolArray(
+ const ConstantPoolArray::NumberOfEntries& small,
+ const ConstantPoolArray::NumberOfEntries& extended);
// Allocates an external array of the specified length and type.
MUST_USE_RESULT AllocationResult AllocateExternalArray(
SlotsBuffer::IGNORE_OVERFLOW);
}
} else if (compacting_ && dst->IsConstantPoolArray()) {
- ConstantPoolArray* constant_pool = ConstantPoolArray::cast(dst);
- for (int i = 0; i < constant_pool->count_of_code_ptr_entries(); i++) {
+ ConstantPoolArray* array = ConstantPoolArray::cast(dst);
+ ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR);
+ while (!code_iter.is_finished()) {
Address code_entry_slot =
- dst_addr + constant_pool->OffsetOfElementAt(i);
+ dst_addr + array->OffsetOfElementAt(code_iter.next_index());
Address code_entry = Memory::Address_at(code_entry_slot);
if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
void ConstantPoolArray::ConstantPoolArrayVerify() {
CHECK(IsConstantPoolArray());
- for (int i = 0; i < count_of_code_ptr_entries(); i++) {
- Address code_entry = get_code_ptr_entry(first_code_ptr_index() + i);
+ ConstantPoolArray::Iterator code_iter(this, ConstantPoolArray::CODE_PTR);
+ while (!code_iter.is_finished()) {
+ Address code_entry = get_code_ptr_entry(code_iter.next_index());
VerifyPointer(Code::GetCodeFromTargetAddress(code_entry));
}
- for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
- VerifyObjectField(OffsetOfElementAt(first_heap_ptr_index() + i));
+ ConstantPoolArray::Iterator heap_iter(this, ConstantPoolArray::HEAP_PTR);
+ while (!heap_iter.is_finished()) {
+ VerifyObjectField(OffsetOfElementAt(heap_iter.next_index()));
}
}
}
-void ConstantPoolArray::set_weak_object_state(
- ConstantPoolArray::WeakObjectState state) {
- int old_layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
- int new_layout_field = WeakObjectStateField::update(old_layout_field, state);
- WRITE_INT_FIELD(this, kArrayLayoutOffset, new_layout_field);
+bool ConstantPoolArray::is_extended_layout() {
+ uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
+ return IsExtendedField::decode(small_layout_1);
}
-ConstantPoolArray::WeakObjectState ConstantPoolArray::get_weak_object_state() {
- int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
- return WeakObjectStateField::decode(layout_field);
+ConstantPoolArray::LayoutSection ConstantPoolArray::final_section() {
+ return is_extended_layout() ? EXTENDED_SECTION : SMALL_SECTION;
}
-int ConstantPoolArray::first_int64_index() {
- return 0;
+int ConstantPoolArray::first_extended_section_index() {
+ ASSERT(is_extended_layout());
+ uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
+ return TotalCountField::decode(small_layout_2);
}
-int ConstantPoolArray::first_code_ptr_index() {
- int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
- return first_int64_index() +
- NumberOfInt64EntriesField::decode(layout_field);
+int ConstantPoolArray::get_extended_section_header_offset() {
+ return RoundUp(SizeFor(NumberOfEntries(this, SMALL_SECTION)), kInt64Size);
}
-int ConstantPoolArray::first_heap_ptr_index() {
- int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
- return first_code_ptr_index() +
- NumberOfCodePtrEntriesField::decode(layout_field);
+ConstantPoolArray::WeakObjectState ConstantPoolArray::get_weak_object_state() {
+ uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
+ return WeakObjectStateField::decode(small_layout_2);
}
-int ConstantPoolArray::first_int32_index() {
- int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
- return first_heap_ptr_index() +
- NumberOfHeapPtrEntriesField::decode(layout_field);
+void ConstantPoolArray::set_weak_object_state(
+ ConstantPoolArray::WeakObjectState state) {
+ uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
+ small_layout_2 = WeakObjectStateField::update(small_layout_2, state);
+ WRITE_INT32_FIELD(this, kSmallLayout2Offset, small_layout_2);
}
-int ConstantPoolArray::count_of_int64_entries() {
- return first_code_ptr_index();
-}
+int ConstantPoolArray::first_index(Type type, LayoutSection section) {
+ int index = 0;
+ if (section == EXTENDED_SECTION) {
+ ASSERT(is_extended_layout());
+ index += first_extended_section_index();
+ }
+ for (Type type_iter = FIRST_TYPE; type_iter < type;
+ type_iter = next_type(type_iter)) {
+ index += number_of_entries(type_iter, section);
+ }
-int ConstantPoolArray::count_of_code_ptr_entries() {
- return first_heap_ptr_index() - first_code_ptr_index();
+ return index;
}
-int ConstantPoolArray::count_of_heap_ptr_entries() {
- return first_int32_index() - first_heap_ptr_index();
+int ConstantPoolArray::last_index(Type type, LayoutSection section) {
+ return first_index(type, section) + number_of_entries(type, section) - 1;
}
-int ConstantPoolArray::count_of_int32_entries() {
- return length() - first_int32_index();
+int ConstantPoolArray::number_of_entries(Type type, LayoutSection section) {
+ if (section == SMALL_SECTION) {
+ uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
+ uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
+ switch (type) {
+ case INT64:
+ return Int64CountField::decode(small_layout_1);
+ case CODE_PTR:
+ return CodePtrCountField::decode(small_layout_1);
+ case HEAP_PTR:
+ return HeapPtrCountField::decode(small_layout_1);
+ case INT32:
+ return Int32CountField::decode(small_layout_2);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+ } else {
+ ASSERT(section == EXTENDED_SECTION && is_extended_layout());
+ int offset = get_extended_section_header_offset();
+ switch (type) {
+ case INT64:
+ offset += kExtendedInt64CountOffset;
+ break;
+ case CODE_PTR:
+ offset += kExtendedCodePtrCountOffset;
+ break;
+ case HEAP_PTR:
+ offset += kExtendedHeapPtrCountOffset;
+ break;
+ case INT32:
+ offset += kExtendedInt32CountOffset;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return READ_INT_FIELD(this, offset);
+ }
}
-void ConstantPoolArray::Init(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- set_length(number_of_int64_entries +
- number_of_code_ptr_entries +
- number_of_heap_ptr_entries +
- number_of_int32_entries);
- int layout_field =
- NumberOfInt64EntriesField::encode(number_of_int64_entries) |
- NumberOfCodePtrEntriesField::encode(number_of_code_ptr_entries) |
- NumberOfHeapPtrEntriesField::encode(number_of_heap_ptr_entries) |
- WeakObjectStateField::encode(NO_WEAK_OBJECTS);
- WRITE_INT_FIELD(this, kArrayLayoutOffset, layout_field);
+ConstantPoolArray::Type ConstantPoolArray::get_type(int index) {
+ LayoutSection section;
+ if (is_extended_layout() && index >= first_extended_section_index()) {
+ section = EXTENDED_SECTION;
+ } else {
+ section = SMALL_SECTION;
+ }
+
+ Type type = FIRST_TYPE;
+ while (index > last_index(type, section)) {
+ type = next_type(type);
+ }
+ ASSERT(type <= LAST_TYPE);
+ return type;
}
int64_t ConstantPoolArray::get_int64_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= 0 && index < first_code_ptr_index());
+ ASSERT(get_type(index) == INT64);
return READ_INT64_FIELD(this, OffsetOfElementAt(index));
}
+
double ConstantPoolArray::get_int64_entry_as_double(int index) {
STATIC_ASSERT(kDoubleSize == kInt64Size);
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= 0 && index < first_code_ptr_index());
+ ASSERT(get_type(index) == INT64);
return READ_DOUBLE_FIELD(this, OffsetOfElementAt(index));
}
Address ConstantPoolArray::get_code_ptr_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_code_ptr_index() && index < first_heap_ptr_index());
+ ASSERT(get_type(index) == CODE_PTR);
return reinterpret_cast<Address>(READ_FIELD(this, OffsetOfElementAt(index)));
}
Object* ConstantPoolArray::get_heap_ptr_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_heap_ptr_index() && index < first_int32_index());
+ ASSERT(get_type(index) == HEAP_PTR);
return READ_FIELD(this, OffsetOfElementAt(index));
}
int32_t ConstantPoolArray::get_int32_entry(int index) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_int32_index() && index < length());
+ ASSERT(get_type(index) == INT32);
return READ_INT32_FIELD(this, OffsetOfElementAt(index));
}
+void ConstantPoolArray::set(int index, int64_t value) {
+ ASSERT(map() == GetHeap()->constant_pool_array_map());
+ ASSERT(get_type(index) == INT64);
+ WRITE_INT64_FIELD(this, OffsetOfElementAt(index), value);
+}
+
+
+void ConstantPoolArray::set(int index, double value) {
+ STATIC_ASSERT(kDoubleSize == kInt64Size);
+ ASSERT(map() == GetHeap()->constant_pool_array_map());
+ ASSERT(get_type(index) == INT64);
+ WRITE_DOUBLE_FIELD(this, OffsetOfElementAt(index), value);
+}
+
+
void ConstantPoolArray::set(int index, Address value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_code_ptr_index() && index < first_heap_ptr_index());
+ ASSERT(get_type(index) == CODE_PTR);
WRITE_FIELD(this, OffsetOfElementAt(index), reinterpret_cast<Object*>(value));
}
void ConstantPoolArray::set(int index, Object* value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_code_ptr_index() && index < first_int32_index());
+ ASSERT(get_type(index) == HEAP_PTR);
WRITE_FIELD(this, OffsetOfElementAt(index), value);
WRITE_BARRIER(GetHeap(), this, OffsetOfElementAt(index), value);
}
-void ConstantPoolArray::set(int index, int64_t value) {
+void ConstantPoolArray::set(int index, int32_t value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_int64_index() && index < first_code_ptr_index());
- WRITE_INT64_FIELD(this, OffsetOfElementAt(index), value);
+ ASSERT(get_type(index) == INT32);
+ WRITE_INT32_FIELD(this, OffsetOfElementAt(index), value);
}
-void ConstantPoolArray::set(int index, double value) {
- STATIC_ASSERT(kDoubleSize == kInt64Size);
- ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= first_int64_index() && index < first_code_ptr_index());
- WRITE_DOUBLE_FIELD(this, OffsetOfElementAt(index), value);
+void ConstantPoolArray::Init(const NumberOfEntries& small) {
+ uint32_t small_layout_1 =
+ Int64CountField::encode(small.count_of(INT64)) |
+ CodePtrCountField::encode(small.count_of(CODE_PTR)) |
+ HeapPtrCountField::encode(small.count_of(HEAP_PTR)) |
+ IsExtendedField::encode(false);
+ uint32_t small_layout_2 =
+ Int32CountField::encode(small.count_of(INT32)) |
+ TotalCountField::encode(small.total_count()) |
+ WeakObjectStateField::encode(NO_WEAK_OBJECTS);
+ WRITE_UINT32_FIELD(this, kSmallLayout1Offset, small_layout_1);
+ WRITE_UINT32_FIELD(this, kSmallLayout2Offset, small_layout_2);
+ if (kHeaderSize != kFirstEntryOffset) {
+ ASSERT(kFirstEntryOffset - kHeaderSize == kInt32Size);
+ WRITE_UINT32_FIELD(this, kHeaderSize, 0); // Zero out header padding.
+ }
}
-void ConstantPoolArray::set(int index, int32_t value) {
- ASSERT(map() == GetHeap()->constant_pool_array_map());
- ASSERT(index >= this->first_int32_index() && index < length());
- WRITE_INT32_FIELD(this, OffsetOfElementAt(index), value);
+void ConstantPoolArray::InitExtended(const NumberOfEntries& small,
+ const NumberOfEntries& extended) {
+ // Initialize small layout fields first.
+ Init(small);
+
+ // Set is_extended_layout field.
+ uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
+ small_layout_1 = IsExtendedField::update(small_layout_1, true);
+ WRITE_INT32_FIELD(this, kSmallLayout1Offset, small_layout_1);
+
+ // Initialize the extended layout fields.
+ int extended_header_offset = get_extended_section_header_offset();
+ WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt64CountOffset,
+ extended.count_of(INT64));
+ WRITE_INT_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset,
+ extended.count_of(CODE_PTR));
+ WRITE_INT_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset,
+ extended.count_of(HEAP_PTR));
+ WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt32CountOffset,
+ extended.count_of(INT32));
+}
+
+
+int ConstantPoolArray::size() {
+ NumberOfEntries small(this, SMALL_SECTION);
+ if (!is_extended_layout()) {
+ return SizeFor(small);
+ } else {
+ NumberOfEntries extended(this, EXTENDED_SECTION);
+ return SizeForExtended(small, extended);
+ }
+}
+
+
+int ConstantPoolArray::length() {
+ uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
+ int length = TotalCountField::decode(small_layout_2);
+ if (is_extended_layout()) {
+ length += number_of_entries(INT64, EXTENDED_SECTION) +
+ number_of_entries(CODE_PTR, EXTENDED_SECTION) +
+ number_of_entries(HEAP_PTR, EXTENDED_SECTION) +
+ number_of_entries(INT32, EXTENDED_SECTION);
+ }
+ return length;
+}
+
+
+int ConstantPoolArray::Iterator::next_index() {
+ ASSERT(!is_finished());
+ int ret = next_index_++;
+ update_section();
+ return ret;
+}
+
+
+bool ConstantPoolArray::Iterator::is_finished() {
+ return next_index_ > array_->last_index(type_, final_section_);
+}
+
+
+void ConstantPoolArray::Iterator::update_section() {
+ if (next_index_ > array_->last_index(type_, current_section_) &&
+ current_section_ != final_section_) {
+ ASSERT(final_section_ == EXTENDED_SECTION);
+ current_section_ = EXTENDED_SECTION;
+ next_index_ = array_->first_index(type_, EXTENDED_SECTION);
+ }
}
reinterpret_cast<FixedDoubleArray*>(this)->length());
}
if (instance_type == CONSTANT_POOL_ARRAY_TYPE) {
- return ConstantPoolArray::SizeFor(
- reinterpret_cast<ConstantPoolArray*>(this)->count_of_int64_entries(),
- reinterpret_cast<ConstantPoolArray*>(this)->count_of_code_ptr_entries(),
- reinterpret_cast<ConstantPoolArray*>(this)->count_of_heap_ptr_entries(),
- reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries());
+ return reinterpret_cast<ConstantPoolArray*>(this)->size();
}
if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
void ConstantPoolArray::ConstantPoolArrayPrint(FILE* out) {
HeapObject::PrintHeader(out, "ConstantPoolArray");
PrintF(out, " - length: %d", length());
- for (int i = 0; i < length(); i++) {
- if (i < first_code_ptr_index()) {
+ for (int i = 0; i <= last_index(INT32, SMALL_SECTION); i++) {
+ if (i < last_index(INT64, SMALL_SECTION)) {
PrintF(out, "\n [%d]: double: %g", i, get_int64_entry_as_double(i));
- } else if (i < first_heap_ptr_index()) {
+ } else if (i <= last_index(CODE_PTR, SMALL_SECTION)) {
PrintF(out, "\n [%d]: code target pointer: %p", i,
reinterpret_cast<void*>(get_code_ptr_entry(i)));
- } else if (i < first_int32_index()) {
+ } else if (i <= last_index(HEAP_PTR, SMALL_SECTION)) {
PrintF(out, "\n [%d]: heap pointer: %p", i,
reinterpret_cast<void*>(get_heap_ptr_entry(i)));
- } else {
+ } else if (i <= last_index(INT32, SMALL_SECTION)) {
PrintF(out, "\n [%d]: int32: %d", i, get_int32_entry(i));
}
}
+ if (is_extended_layout()) {
+ PrintF(out, "\n Extended section:");
+ for (int i = first_extended_section_index();
+ i <= last_index(INT32, EXTENDED_SECTION); i++) {
+ if (i < last_index(INT64, EXTENDED_SECTION)) {
+ PrintF(out, "\n [%d]: double: %g", i, get_int64_entry_as_double(i));
+ } else if (i <= last_index(CODE_PTR, EXTENDED_SECTION)) {
+ PrintF(out, "\n [%d]: code target pointer: %p", i,
+ reinterpret_cast<void*>(get_code_ptr_entry(i)));
+ } else if (i <= last_index(HEAP_PTR, EXTENDED_SECTION)) {
+ PrintF(out, "\n [%d]: heap pointer: %p", i,
+ reinterpret_cast<void*>(get_heap_ptr_entry(i)));
+ } else if (i <= last_index(INT32, EXTENDED_SECTION)) {
+ PrintF(out, "\n [%d]: int32: %d", i, get_int32_entry(i));
+ }
+ }
+ }
PrintF(out, "\n");
}
void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
- ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
- for (int i = 0; i < constant_pool->count_of_code_ptr_entries(); i++) {
- int index = constant_pool->first_code_ptr_index() + i;
- Address code_entry =
- reinterpret_cast<Address>(constant_pool->RawFieldOfElementAt(index));
+ ConstantPoolArray* array = ConstantPoolArray::cast(object);
+ ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR);
+ while (!code_iter.is_finished()) {
+ Address code_entry = reinterpret_cast<Address>(
+ array->RawFieldOfElementAt(code_iter.next_index()));
StaticVisitor::VisitCodeEntry(heap, code_entry);
}
- for (int i = 0; i < constant_pool->count_of_heap_ptr_entries(); i++) {
- int index = constant_pool->first_heap_ptr_index() + i;
- Object** slot = constant_pool->RawFieldOfElementAt(index);
+
+ ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR);
+ while (!heap_iter.is_finished()) {
+ Object** slot = array->RawFieldOfElementAt(heap_iter.next_index());
HeapObject* object = HeapObject::cast(*slot);
heap->mark_compact_collector()->RecordSlot(slot, slot, object);
bool is_weak_object =
- (constant_pool->get_weak_object_state() ==
+ (array->get_weak_object_state() ==
ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE &&
Code::IsWeakObjectInOptimizedCode(object)) ||
- (constant_pool->get_weak_object_state() ==
+ (array->get_weak_object_state() ==
ConstantPoolArray::WEAK_OBJECTS_IN_IC &&
Code::IsWeakObjectInIC(object));
if (!is_weak_object) {
void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
- for (int i = 0; i < count_of_code_ptr_entries(); i++) {
- int index = first_code_ptr_index() + i;
- v->VisitCodeEntry(reinterpret_cast<Address>(RawFieldOfElementAt(index)));
+ ConstantPoolArray::Iterator code_iter(this, ConstantPoolArray::CODE_PTR);
+ while (!code_iter.is_finished()) {
+ v->VisitCodeEntry(reinterpret_cast<Address>(
+ RawFieldOfElementAt(code_iter.next_index())));
}
- for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
- int index = first_heap_ptr_index() + i;
- v->VisitPointer(RawFieldOfElementAt(index));
+
+ ConstantPoolArray::Iterator heap_iter(this, ConstantPoolArray::HEAP_PTR);
+ while (!heap_iter.is_finished()) {
+ v->VisitPointer(RawFieldOfElementAt(heap_iter.next_index()));
+ }
+}
+
+
+void ConstantPoolArray::ClearPtrEntries(Isolate* isolate) {
+ Type type[] = { CODE_PTR, HEAP_PTR };
+ Address default_value[] = {
+ isolate->builtins()->builtin(Builtins::kIllegal)->entry(),
+ reinterpret_cast<Address>(isolate->heap()->undefined_value()) };
+
+ for (int i = 0; i < 2; ++i) {
+ for (int s = 0; s <= final_section(); ++s) {
+ LayoutSection section = static_cast<LayoutSection>(s);
+ if (number_of_entries(type[i], section) > 0) {
+ int offset = OffsetOfElementAt(first_index(type[i], section));
+ MemsetPointer(
+ reinterpret_cast<Address*>(HeapObject::RawField(this, offset)),
+ default_value[i],
+ number_of_entries(type[i], section));
+ }
+ }
}
}
// ConstantPoolArray describes a fixed-sized array containing constant pool
-// entires.
-// The format of the pool is:
-// [0]: Field holding the first index which is a raw code target pointer entry
-// [1]: Field holding the first index which is a heap pointer entry
-// [2]: Field holding the first index which is a int32 entry
-// [3] ... [first_code_ptr_index() - 1] : 64 bit entries
-// [first_code_ptr_index()] ... [first_heap_ptr_index() - 1] : code pointers
-// [first_heap_ptr_index()] ... [first_int32_index() - 1] : heap pointers
-// [first_int32_index()] ... [length - 1] : 32 bit entries
-class ConstantPoolArray: public FixedArrayBase {
+// entries.
+//
+// A ConstantPoolArray can be structured in two different ways depending upon
+// whether it is extended or small. The is_extended_layout() method can be used
+// to discover which layout the constant pool has.
+//
+// The format of a small constant pool is:
+// [kSmallLayout1Offset] : Small section layout bitmap 1
+// [kSmallLayout2Offset] : Small section layout bitmap 2
+// [first_index(INT64, SMALL_SECTION)] : 64 bit entries
+// ... : ...
+// [first_index(CODE_PTR, SMALL_SECTION)] : code pointer entries
+// ... : ...
+// [first_index(HEAP_PTR, SMALL_SECTION)] : heap pointer entries
+// ... : ...
+// [first_index(INT32, SMALL_SECTION)] : 32 bit entries
+// ... : ...
+//
+// If the constant pool has an extended layout, the extended section constant
+// pool also contains an extended section, which has the following format at
+// location get_extended_section_header_offset():
+// [kExtendedInt64CountOffset] : count of extended 64 bit entries
+// [kExtendedCodePtrCountOffset] : count of extended code pointers
+// [kExtendedHeapPtrCountOffset] : count of extended heap pointers
+// [kExtendedInt32CountOffset] : count of extended 32 bit entries
+// [first_index(INT64, EXTENDED_SECTION)] : 64 bit entries
+// ... : ...
+// [first_index(CODE_PTR, EXTENDED_SECTION)]: code pointer entries
+// ... : ...
+// [first_index(HEAP_PTR, EXTENDED_SECTION)]: heap pointer entries
+// ... : ...
+// [first_index(INT32, EXTENDED_SECTION)] : 32 bit entries
+// ... : ...
+//
+class ConstantPoolArray: public HeapObject {
public:
enum WeakObjectState {
NO_WEAK_OBJECTS,
WEAK_OBJECTS_IN_IC
};
- // Getters for the field storing the first index for different type entries.
- inline int first_code_ptr_index();
- inline int first_heap_ptr_index();
- inline int first_int64_index();
- inline int first_int32_index();
+ enum Type {
+ INT64 = 0,
+ CODE_PTR,
+ HEAP_PTR,
+ INT32,
+ // Number of types stored by the ConstantPoolArrays.
+ NUMBER_OF_TYPES,
+ FIRST_TYPE = INT64,
+ LAST_TYPE = INT32
+ };
+
+ enum LayoutSection {
+ SMALL_SECTION = 0,
+ EXTENDED_SECTION
+ };
+
+ class NumberOfEntries BASE_EMBEDDED {
+ public:
+ inline NumberOfEntries(int int64_count, int code_ptr_count,
+ int heap_ptr_count, int int32_count) {
+ element_counts_[INT64] = int64_count;
+ element_counts_[CODE_PTR] = code_ptr_count;
+ element_counts_[HEAP_PTR] = heap_ptr_count;
+ element_counts_[INT32] = int32_count;
+ }
+
+ inline NumberOfEntries(ConstantPoolArray* array, LayoutSection section) {
+ element_counts_[INT64] = array->number_of_entries(INT64, section);
+ element_counts_[CODE_PTR] = array->number_of_entries(CODE_PTR, section);
+ element_counts_[HEAP_PTR] = array->number_of_entries(HEAP_PTR, section);
+ element_counts_[INT32] = array->number_of_entries(INT32, section);
+ }
+
+ inline int count_of(Type type) const {
+ ASSERT(type < NUMBER_OF_TYPES);
+ return element_counts_[type];
+ }
+
+ inline int total_count() const {
+ int count = 0;
+ for (int i = 0; i < NUMBER_OF_TYPES; i++) {
+ count += element_counts_[i];
+ }
+ return count;
+ }
+
+ inline int are_in_range(int min, int max) const {
+ for (int i = FIRST_TYPE; i < NUMBER_OF_TYPES; i++) {
+ if (element_counts_[i] < min || element_counts_[i] > max) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private:
+ int element_counts_[NUMBER_OF_TYPES];
+ };
+
+ class Iterator BASE_EMBEDDED {
+ public:
+ inline Iterator(ConstantPoolArray* array, Type type)
+ : array_(array), type_(type), final_section_(array->final_section()) {
+ current_section_ = SMALL_SECTION;
+ next_index_ = array->first_index(type, SMALL_SECTION);
+ update_section();
+ }
+
+ inline int next_index();
+ inline bool is_finished();
+ private:
+ inline void update_section();
+ ConstantPoolArray* array_;
+ const Type type_;
+ const LayoutSection final_section_;
+
+ LayoutSection current_section_;
+ int next_index_;
+ };
+
+ // Getters for the first index, the last index and the count of entries of
+ // a given type for a given layout section.
+ inline int first_index(Type type, LayoutSection layout_section);
+ inline int last_index(Type type, LayoutSection layout_section);
+ inline int number_of_entries(Type type, LayoutSection layout_section);
- // Getters for counts of different type entries.
- inline int count_of_code_ptr_entries();
- inline int count_of_heap_ptr_entries();
- inline int count_of_int64_entries();
- inline int count_of_int32_entries();
+ // Returns the type of the entry at the given index.
+ inline Type get_type(int index);
// Setter and getter for pool elements.
inline Address get_code_ptr_entry(int index);
inline int32_t get_int32_entry(int index);
inline double get_int64_entry_as_double(int index);
- // Setter and getter for weak objects state
- inline void set_weak_object_state(WeakObjectState state);
- inline WeakObjectState get_weak_object_state();
-
inline void set(int index, Address value);
inline void set(int index, Object* value);
inline void set(int index, int64_t value);
inline void set(int index, double value);
inline void set(int index, int32_t value);
- // Set up initial state.
- inline void Init(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries);
+ // Setter and getter for weak objects state
+ inline void set_weak_object_state(WeakObjectState state);
+ inline WeakObjectState get_weak_object_state();
+
+ // Returns true if the constant pool has an extended layout, false if it has
+ // only the small layout.
+ inline bool is_extended_layout();
+
+ // Returns the last LayoutSection in this constant pool array.
+ inline LayoutSection final_section();
+
+ // Set up initial state for a small layout constant pool array.
+ inline void Init(const NumberOfEntries& small);
+
+ // Set up initial state for an extended layout constant pool array.
+ inline void InitExtended(const NumberOfEntries& small,
+ const NumberOfEntries& extended);
+
+ // Clears the pointer entries with GC safe values.
+ void ClearPtrEntries(Isolate* isolate);
+
+ // returns the total number of entries in the constant pool array.
+ inline int length();
// Garbage collection support.
- inline static int SizeFor(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- return RoundUp(OffsetAt(number_of_int64_entries,
- number_of_code_ptr_entries,
- number_of_heap_ptr_entries,
- number_of_int32_entries),
- kPointerSize);
+ inline int size();
+
+ inline static int SizeFor(const NumberOfEntries& small) {
+ int size = kFirstEntryOffset +
+ (small.count_of(INT64) * kInt64Size) +
+ (small.count_of(CODE_PTR) * kPointerSize) +
+ (small.count_of(HEAP_PTR) * kPointerSize) +
+ (small.count_of(INT32) * kInt32Size);
+ return RoundUp(size, kPointerSize);
+ }
+
+ inline static int SizeForExtended(const NumberOfEntries& small,
+ const NumberOfEntries& extended) {
+ int size = SizeFor(small);
+ size = RoundUp(size, kInt64Size); // Align extended header to 64 bits.
+ size += kExtendedFirstOffset +
+ (extended.count_of(INT64) * kInt64Size) +
+ (extended.count_of(CODE_PTR) * kPointerSize) +
+ (extended.count_of(HEAP_PTR) * kPointerSize) +
+ (extended.count_of(INT32) * kInt32Size);
+ return RoundUp(size, kPointerSize);
+ }
+
+ inline static int entry_size(Type type) {
+ switch (type) {
+ case INT32:
+ return kInt32Size;
+ case INT64:
+ return kInt64Size;
+ case CODE_PTR:
+ case HEAP_PTR:
+ return kPointerSize;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
}
// Code Generation support.
inline int OffsetOfElementAt(int index) {
- ASSERT(index < length());
- if (index >= first_int32_index()) {
- return OffsetAt(count_of_int64_entries(), count_of_code_ptr_entries(),
- count_of_heap_ptr_entries(), index - first_int32_index());
- } else if (index >= first_heap_ptr_index()) {
- return OffsetAt(count_of_int64_entries(), count_of_code_ptr_entries(),
- index - first_heap_ptr_index(), 0);
- } else if (index >= first_code_ptr_index()) {
- return OffsetAt(count_of_int64_entries(), index - first_code_ptr_index(),
- 0, 0);
+ int offset;
+ LayoutSection section;
+ if (is_extended_layout() && index >= first_extended_section_index()) {
+ section = EXTENDED_SECTION;
+ offset = get_extended_section_header_offset() + kExtendedFirstOffset;
} else {
- return OffsetAt(index, 0, 0, 0);
+ section = SMALL_SECTION;
+ offset = kFirstEntryOffset;
}
+
+ // Add offsets for the preceding type sections.
+ ASSERT(index <= last_index(LAST_TYPE, section));
+ for (Type type = FIRST_TYPE; index > last_index(type, section);
+ type = next_type(type)) {
+ offset += entry_size(type) * number_of_entries(type, section);
+ }
+
+ // Add offset for the index in it's type.
+ Type type = get_type(index);
+ offset += entry_size(type) * (index - first_index(type, section));
+ return offset;
}
// Casting.
return HeapObject::RawField(this, OffsetOfElementAt(index));
}
- // Layout description.
- static const int kArrayLayoutOffset = FixedArray::kHeaderSize;
- static const int kFirstOffset = kArrayLayoutOffset + kPointerSize;
-
- static const int kFieldBitSize = 10;
- static const int kMaxEntriesPerType = (1 << kFieldBitSize) - 1;
-
- class NumberOfInt64EntriesField: public BitField<int, 0, kFieldBitSize> {};
- class NumberOfCodePtrEntriesField: public BitField<int, 10, kFieldBitSize> {};
- class NumberOfHeapPtrEntriesField: public BitField<int, 20, kFieldBitSize> {};
- class WeakObjectStateField: public BitField<WeakObjectState, 30, 2> {};
+ // Small Layout description.
+ static const int kSmallLayout1Offset = HeapObject::kHeaderSize;
+ static const int kSmallLayout2Offset = kSmallLayout1Offset + kInt32Size;
+ static const int kHeaderSize = kSmallLayout2Offset + kInt32Size;
+ static const int kFirstEntryOffset = ROUND_UP(kHeaderSize, kInt64Size);
+
+ static const int kSmallLayoutCountBits = 10;
+ static const int kMaxSmallEntriesPerType = (1 << kSmallLayoutCountBits) - 1;
+
+ // Fields in kSmallLayout1Offset.
+ class Int64CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
+ class CodePtrCountField: public BitField<int, 11, kSmallLayoutCountBits> {};
+ class HeapPtrCountField: public BitField<int, 21, kSmallLayoutCountBits> {};
+ class IsExtendedField: public BitField<bool, 31, 1> {};
+
+ // Fields in kSmallLayout2Offset.
+ class Int32CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
+ class TotalCountField: public BitField<int, 11, 12> {};
+ class WeakObjectStateField: public BitField<WeakObjectState, 23, 2> {};
+
+ // Extended layout description, which starts at
+ // get_extended_section_header_offset().
+ static const int kExtendedInt64CountOffset = 0;
+ static const int kExtendedCodePtrCountOffset =
+ kExtendedInt64CountOffset + kPointerSize;
+ static const int kExtendedHeapPtrCountOffset =
+ kExtendedCodePtrCountOffset + kPointerSize;
+ static const int kExtendedInt32CountOffset =
+ kExtendedHeapPtrCountOffset + kPointerSize;
+ static const int kExtendedFirstOffset =
+ kExtendedInt32CountOffset + kPointerSize;
// Dispatched behavior.
void ConstantPoolIterateBody(ObjectVisitor* v);
DECLARE_VERIFIER(ConstantPoolArray)
private:
- inline static int OffsetAt(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- return kFirstOffset
- + (number_of_int64_entries * kInt64Size)
- + (number_of_code_ptr_entries * kPointerSize)
- + (number_of_heap_ptr_entries * kPointerSize)
- + (number_of_int32_entries * kInt32Size);
+ inline int first_extended_section_index();
+ inline int get_extended_section_header_offset();
+
+ inline static Type next_type(Type type) {
+ ASSERT(type >= FIRST_TYPE && type < NUMBER_OF_TYPES);
+ int type_int = static_cast<int>(type);
+ return static_cast<Type>(++type_int);
}
DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
using namespace v8::internal;
+static ConstantPoolArray::Type kTypes[] = { ConstantPoolArray::INT64,
+ ConstantPoolArray::CODE_PTR,
+ ConstantPoolArray::HEAP_PTR,
+ ConstantPoolArray::INT32 };
+static ConstantPoolArray::LayoutSection kSmall =
+ ConstantPoolArray::SMALL_SECTION;
+static ConstantPoolArray::LayoutSection kExtended =
+ ConstantPoolArray::EXTENDED_SECTION;
Code* DummyCode(LocalContext* context) {
CompileRun("function foo() {};");
}
-TEST(ConstantPool) {
+TEST(ConstantPoolSmall) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
v8::HandleScope scope(context->GetIsolate());
// Check construction.
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 1, 2, 1);
- CHECK_EQ(array->count_of_int64_entries(), 3);
- CHECK_EQ(array->count_of_code_ptr_entries(), 1);
- CHECK_EQ(array->count_of_heap_ptr_entries(), 2);
- CHECK_EQ(array->count_of_int32_entries(), 1);
- CHECK_EQ(array->length(), 7);
- CHECK_EQ(array->first_int64_index(), 0);
- CHECK_EQ(array->first_code_ptr_index(), 3);
- CHECK_EQ(array->first_heap_ptr_index(), 4);
- CHECK_EQ(array->first_int32_index(), 6);
+ ConstantPoolArray::NumberOfEntries small(3, 1, 2, 1);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+
+ int expected_counts[] = { 3, 1, 2, 1 };
+ int expected_first_idx[] = { 0, 3, 4, 6 };
+ int expected_last_idx[] = { 2, 3, 5, 6 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(expected_counts[i], array->number_of_entries(kTypes[i], kSmall));
+ CHECK_EQ(expected_first_idx[i], array->first_index(kTypes[i], kSmall));
+ CHECK_EQ(expected_last_idx[i], array->last_index(kTypes[i], kSmall));
+ }
+ CHECK(!array->is_extended_layout());
// Check getters and setters.
int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
array->set(4, code);
array->set(5, *object);
array->set(6, 50);
- CHECK_EQ(array->get_int64_entry(0), big_number);
- CHECK_EQ(array->get_int64_entry_as_double(1), 0.5);
- CHECK_EQ(array->get_int64_entry_as_double(2), 3e-24);
- CHECK_EQ(array->get_code_ptr_entry(3), code->entry());
- CHECK_EQ(array->get_heap_ptr_entry(4), code);
- CHECK_EQ(array->get_heap_ptr_entry(5), *object);
- CHECK_EQ(array->get_int32_entry(6), 50);
+ CHECK_EQ(big_number, array->get_int64_entry(0));
+ CHECK_EQ(0.5, array->get_int64_entry_as_double(1));
+ CHECK_EQ(3e-24, array->get_int64_entry_as_double(2));
+ CHECK_EQ(code->entry(), array->get_code_ptr_entry(3));
+ CHECK_EQ(code, array->get_heap_ptr_entry(4));
+ CHECK_EQ(*object, array->get_heap_ptr_entry(5));
+ CHECK_EQ(50, array->get_int32_entry(6));
// Check pointers are updated on GC.
Object* old_ptr = array->get_heap_ptr_entry(5);
CHECK_NE(*object, old_ptr);
CHECK_EQ(*object, new_ptr);
}
+
+
+TEST(ConstantPoolExtended) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ // Check construction.
+ ConstantPoolArray::NumberOfEntries small(1, 2, 3, 4);
+ ConstantPoolArray::NumberOfEntries extended(5, 6, 7, 8);
+ Handle<ConstantPoolArray> array =
+ factory->NewExtendedConstantPoolArray(small, extended);
+
+ // Check small section.
+ int small_counts[] = { 1, 2, 3, 4 };
+ int small_first_idx[] = { 0, 1, 3, 6 };
+ int small_last_idx[] = { 0, 2, 5, 9 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(small_counts[i], array->number_of_entries(kTypes[i], kSmall));
+ CHECK_EQ(small_first_idx[i], array->first_index(kTypes[i], kSmall));
+ CHECK_EQ(small_last_idx[i], array->last_index(kTypes[i], kSmall));
+ }
+
+ // Check extended layout.
+ CHECK(array->is_extended_layout());
+ int extended_counts[] = { 5, 6, 7, 8 };
+ int extended_first_idx[] = { 10, 15, 21, 28 };
+ int extended_last_idx[] = { 14, 20, 27, 35 };
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(extended_counts[i],
+ array->number_of_entries(kTypes[i], kExtended));
+ CHECK_EQ(extended_first_idx[i], array->first_index(kTypes[i], kExtended));
+ CHECK_EQ(extended_last_idx[i], array->last_index(kTypes[i], kExtended));
+ }
+
+ // Check small and large section's don't overlap.
+ int64_t small_section_int64 = V8_2PART_UINT64_C(0x56781234, DEF09ABC);
+ Code* small_section_code_ptr = DummyCode(&context);
+ Handle<Object> small_section_heap_ptr = factory->NewHeapNumber(4.0);
+ int32_t small_section_int32 = 0xab12cd45;
+
+ int64_t extended_section_int64 = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
+ Code* extended_section_code_ptr = DummyCode(&context);
+ Handle<Object> extended_section_heap_ptr = factory->NewHeapNumber(4.0);
+ int32_t extended_section_int32 = 0xef67ab89;
+
+ for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
+ i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
+ array->set(i, small_section_int64);
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
+ array->set(i, small_section_code_ptr->entry());
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
+ array->set(i, *small_section_heap_ptr);
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
+ array->set(i, small_section_int32);
+ }
+ }
+ for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
+ i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
+ array->set(i, extended_section_int64);
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
+ array->set(i, extended_section_code_ptr->entry());
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
+ array->set(i, *extended_section_heap_ptr);
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
+ array->set(i, extended_section_int32);
+ }
+ }
+
+ for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
+ i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
+ CHECK_EQ(small_section_int64, array->get_int64_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
+ CHECK_EQ(small_section_code_ptr->entry(), array->get_code_ptr_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
+ CHECK_EQ(*small_section_heap_ptr, array->get_heap_ptr_entry(i));
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
+ CHECK_EQ(small_section_int32, array->get_int32_entry(i));
+ }
+ }
+ for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
+ i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
+ if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
+ CHECK_EQ(extended_section_int64, array->get_int64_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
+ CHECK_EQ(extended_section_code_ptr->entry(),
+ array->get_code_ptr_entry(i));
+ } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
+ CHECK_EQ(*extended_section_heap_ptr, array->get_heap_ptr_entry(i));
+ } else {
+ CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
+ CHECK_EQ(extended_section_int32, array->get_int32_entry(i));
+ }
+ }
+ // Check pointers are updated on GC in extended section.
+ int index = array->first_index(ConstantPoolArray::HEAP_PTR, kExtended);
+ Object* old_ptr = array->get_heap_ptr_entry(index);
+ CHECK_EQ(*extended_section_heap_ptr, old_ptr);
+ heap->CollectGarbage(NEW_SPACE);
+ Object* new_ptr = array->get_heap_ptr_entry(index);
+ CHECK_NE(*extended_section_heap_ptr, old_ptr);
+ CHECK_EQ(*extended_section_heap_ptr, new_ptr);
+}
+
+
+static void CheckIterator(Handle<ConstantPoolArray> array,
+ ConstantPoolArray::Type type,
+ int expected_indexes[],
+ int count) {
+ int i = 0;
+ ConstantPoolArray::Iterator iter(*array, type);
+ while (!iter.is_finished()) {
+ CHECK_EQ(expected_indexes[i++], iter.next_index());
+ }
+ CHECK_EQ(count, i);
+}
+
+
+TEST(ConstantPoolIteratorSmall) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(1, 5, 2, 0);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+
+ int expected_int64_indexs[] = { 0 };
+ CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 1);
+ int expected_code_indexs[] = { 1, 2, 3, 4, 5 };
+ CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 5);
+ int expected_heap_indexs[] = { 6, 7 };
+ CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 2);
+ int expected_int32_indexs[1];
+ CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 0);
+}
+
+
+TEST(ConstantPoolIteratorExtended) {
+ LocalContext context;
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+
+ ConstantPoolArray::NumberOfEntries small(1, 0, 0, 4);
+ ConstantPoolArray::NumberOfEntries extended(5, 0, 3, 0);
+ Handle<ConstantPoolArray> array =
+ factory->NewExtendedConstantPoolArray(small, extended);
+
+ int expected_int64_indexs[] = { 0, 5, 6, 7, 8, 9 };
+ CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 6);
+ int expected_code_indexs[1];
+ CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 0);
+ int expected_heap_indexs[] = { 10, 11, 12 };
+ CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 3);
+ int expected_int32_indexs[] = { 1, 2, 3, 4 };
+ CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 4);
+}