Commit ae6496e6 authored by rmcilroy@chromium.org's avatar rmcilroy@chromium.org

[Arm]: Optimize ConstantPoolBuilder::Populate code by minimizing calls to OffsetOfElementAt

Calling OffsetOfElementAt becomes expensive when compiling functions with many
constant pool entries.  This was causing a regression in MandreelLatency due
to the time spent populating the constant pool array for large compiled
functions.

This change avoids calling OffsetOfElementAt for each entry, and instead keeps
track of the current offsets in ConstantPoolBuilder::Populate.  This gives the
following improvements on a Nexus 5:

                     Inline CP  |  OOL CP (before CL)  |  OOL CP (after CL)
Mandreel:               4305    |        3961          |       4120
MandreelLatency:        2298    |        1198          |       1994
Octane Score:           5197    |        4982          |       5152

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/376973002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22293 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 68036255
......@@ -3586,7 +3586,6 @@ ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
rmode != RelocInfo::STATEMENT_POSITION &&
rmode != RelocInfo::CONST_POOL);
// Try to merge entries which won't be patched.
int merged_index = -1;
ConstantPoolArray::LayoutSection entry_section = current_section_;
......@@ -3656,8 +3655,22 @@ void ConstantPoolBuilder::Populate(Assembler* assm,
constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
}
ConstantPoolArray::NumberOfEntries small_idx;
ConstantPoolArray::NumberOfEntries extended_idx;
// Set up initial offsets.
int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
[ConstantPoolArray::NUMBER_OF_TYPES];
for (int section = 0; section <= constant_pool->final_section(); section++) {
int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
? small_entries()->total_count()
: 0;
for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
if (number_of_entries_[section].count_of(type) != 0) {
offsets[section][type] = constant_pool->OffsetOfElementAt(
number_of_entries_[section].base_of(type) + section_start);
}
}
}
for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
entry != entries_.end(); entry++) {
RelocInfo rinfo = entry->rinfo_;
......@@ -3667,27 +3680,21 @@ void ConstantPoolBuilder::Populate(Assembler* assm,
// Update constant pool if necessary and get the entry's offset.
int offset;
if (entry->merged_index_ == -1) {
int index;
if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) {
index = small_entries()->total_count() +
extended_entries()->base_of(type) + extended_idx.count_of(type);
extended_idx.increment(type);
} else {
ASSERT(entry->section_ == ConstantPoolArray::SMALL_SECTION);
index = small_entries()->base_of(type) + small_idx.count_of(type);
small_idx.increment(type);
}
offset = offsets[entry->section_][type];
offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
if (type == ConstantPoolArray::INT64) {
constant_pool->set(index, rinfo.data64());
constant_pool->set_at_offset(offset, rinfo.data64());
} else if (type == ConstantPoolArray::INT32) {
constant_pool->set(index, static_cast<int32_t>(rinfo.data()));
constant_pool->set_at_offset(offset, rinfo.data());
} else if (type == ConstantPoolArray::CODE_PTR) {
constant_pool->set(index, reinterpret_cast<Address>(rinfo.data()));
constant_pool->set_at_offset(offset,
reinterpret_cast<Address>(rinfo.data()));
} else {
ASSERT(type == ConstantPoolArray::HEAP_PTR);
constant_pool->set(index, reinterpret_cast<Object*>(rinfo.data()));
constant_pool->set_at_offset(offset,
reinterpret_cast<Object*>(rinfo.data()));
}
offset = constant_pool->OffsetOfElementAt(index) - kHeapObjectTag;
offset -= kHeapObjectTag;
entry->merged_index_ = offset; // Stash offset for merged entries.
} else {
ASSERT(entry->merged_index_ < (entry - entries_.begin()));
......@@ -3724,9 +3731,6 @@ void ConstantPoolBuilder::Populate(Assembler* assm,
rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
}
}
ASSERT(small_idx.equals(*small_entries()));
ASSERT(extended_idx.equals(*extended_entries()));
}
......
......@@ -2462,6 +2462,15 @@ int ConstantPoolArray::number_of_entries(Type type, LayoutSection section) {
}
bool ConstantPoolArray::offset_is_type(int offset, Type type) {
return (offset >= OffsetOfElementAt(first_index(type, SMALL_SECTION)) &&
offset <= OffsetOfElementAt(last_index(type, SMALL_SECTION))) ||
(is_extended_layout() &&
offset >= OffsetOfElementAt(first_index(type, EXTENDED_SECTION)) &&
offset <= OffsetOfElementAt(last_index(type, EXTENDED_SECTION)));
}
ConstantPoolArray::Type ConstantPoolArray::get_type(int index) {
LayoutSection section;
if (is_extended_layout() && index >= first_extended_section_index()) {
......@@ -2552,6 +2561,43 @@ void ConstantPoolArray::set(int index, int32_t value) {
}
void ConstantPoolArray::set_at_offset(int offset, int32_t value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(offset_is_type(offset, INT32));
WRITE_INT32_FIELD(this, offset, value);
}
void ConstantPoolArray::set_at_offset(int offset, int64_t value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(offset_is_type(offset, INT64));
WRITE_INT64_FIELD(this, offset, value);
}
void ConstantPoolArray::set_at_offset(int offset, double value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(offset_is_type(offset, INT64));
WRITE_DOUBLE_FIELD(this, offset, value);
}
void ConstantPoolArray::set_at_offset(int offset, Address value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(offset_is_type(offset, CODE_PTR));
WRITE_FIELD(this, offset, reinterpret_cast<Object*>(value));
WRITE_BARRIER(GetHeap(), this, offset, reinterpret_cast<Object*>(value));
}
void ConstantPoolArray::set_at_offset(int offset, Object* value) {
ASSERT(map() == GetHeap()->constant_pool_array_map());
ASSERT(offset_is_type(offset, HEAP_PTR));
WRITE_FIELD(this, offset, value);
WRITE_BARRIER(GetHeap(), this, offset, value);
}
void ConstantPoolArray::Init(const NumberOfEntries& small) {
uint32_t small_layout_1 =
Int64CountField::encode(small.count_of(INT64)) |
......
......@@ -3125,7 +3125,8 @@ class ConstantPoolArray: public HeapObject {
enum LayoutSection {
SMALL_SECTION = 0,
EXTENDED_SECTION
EXTENDED_SECTION,
NUMBER_OF_LAYOUT_SECTIONS
};
class NumberOfEntries BASE_EMBEDDED {
......@@ -3204,6 +3205,7 @@ class ConstantPoolArray: public HeapObject {
// Returns the type of the entry at the given index.
inline Type get_type(int index);
inline bool offset_is_type(int offset, Type type);
// Setter and getter for pool elements.
inline Address get_code_ptr_entry(int index);
......@@ -3218,6 +3220,13 @@ class ConstantPoolArray: public HeapObject {
inline void set(int index, double value);
inline void set(int index, int32_t value);
// Setters which take a raw offset rather than an index (for code generation).
inline void set_at_offset(int offset, int32_t value);
inline void set_at_offset(int offset, int64_t value);
inline void set_at_offset(int offset, double value);
inline void set_at_offset(int offset, Address value);
inline void set_at_offset(int offset, Object* value);
// Setter and getter for weak objects state
inline void set_weak_object_state(WeakObjectState state);
inline WeakObjectState get_weak_object_state();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment