Revision: 22293
Author:   [email protected]
Date:     Wed Jul  9 09:08:37 2014 UTC
Log: [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

[email protected]

Review URL: https://codereview.chromium.org/376973002
http://code.google.com/p/v8/source/detail?r=22293

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Thu Jul 3 17:01:14 2014 UTC +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Wed Jul 9 09:08:37 2014 UTC
@@ -3586,7 +3586,6 @@
          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 @@
         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 @@
     // 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 @@
rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
     }
   }
-
-  ASSERT(small_idx.equals(*small_entries()));
-  ASSERT(extended_idx.equals(*extended_entries()));
 }


=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Tue Jul  8 08:44:45 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Jul  9 09:08:37 2014 UTC
@@ -2460,6 +2460,15 @@
     return READ_INT_FIELD(this, offset);
   }
 }
+
+
+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) {
@@ -2550,6 +2559,43 @@
   ASSERT(get_type(index) == INT32);
   WRITE_INT32_FIELD(this, OffsetOfElementAt(index), 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) {
=======================================
--- /branches/bleeding_edge/src/objects.h       Tue Jul  8 08:44:45 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Wed Jul  9 09:08:37 2014 UTC
@@ -3125,7 +3125,8 @@

   enum LayoutSection {
     SMALL_SECTION = 0,
-    EXTENDED_SECTION
+    EXTENDED_SECTION,
+    NUMBER_OF_LAYOUT_SECTIONS
   };

   class NumberOfEntries BASE_EMBEDDED {
@@ -3204,6 +3205,7 @@

   // 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 @@
   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();

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to