Revision: 7069
Author: [email protected]
Date: Mon Mar  7 00:35:19 2011
Log: Optimize loads from root-array in X64.

Move the value of the root-array register to offset 128 from the start of
the root array. This allows indices 16..31 to be reached using only an
8-bit displacement, saving three bytes per access.

Review URL: http://codereview.chromium.org/6594115
http://code.google.com/p/v8/source/detail?r=7069

Modified:
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/x64/code-stubs-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/deoptimizer-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/src/x64/macro-assembler-x64.h

=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Feb 22 02:05:30 2011
+++ /branches/bleeding_edge/src/heap.h  Mon Mar  7 00:35:19 2011
@@ -49,7 +49,6 @@
V(Map, one_pointer_filler_map, OnePointerFillerMap) \ V(Map, two_pointer_filler_map, TwoPointerFillerMap) \ /* Cluster the most popular ones in a few cache lines here at the top. */ \ - V(Smi, stack_limit, StackLimit) \ V(Object, undefined_value, UndefinedValue) \ V(Object, the_hole_value, TheHoleValue) \ V(Object, null_value, NullValue) \
@@ -62,21 +61,29 @@
V(Map, fixed_cow_array_map, FixedCOWArrayMap) \ V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \ V(Map, meta_map, MetaMap) \ - V(Object, termination_exception, TerminationException) \ V(Map, hash_table_map, HashTableMap) \ + V(Smi, stack_limit, StackLimit) \ + V(FixedArray, number_string_cache, NumberStringCache) \ + V(Object, instanceof_cache_function, InstanceofCacheFunction) \ + V(Object, instanceof_cache_map, InstanceofCacheMap) \ + V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \ + V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ + V(Object, termination_exception, TerminationException) \ V(FixedArray, empty_fixed_array, EmptyFixedArray) \ V(ByteArray, empty_byte_array, EmptyByteArray) \ + V(String, empty_string, EmptyString) \ + V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \ V(Map, string_map, StringMap) \ V(Map, ascii_string_map, AsciiStringMap) \ V(Map, symbol_map, SymbolMap) \ + V(Map, cons_string_map, ConsStringMap) \ + V(Map, cons_ascii_string_map, ConsAsciiStringMap) \ V(Map, ascii_symbol_map, AsciiSymbolMap) \ V(Map, cons_symbol_map, ConsSymbolMap) \ V(Map, cons_ascii_symbol_map, ConsAsciiSymbolMap) \ V(Map, external_symbol_map, ExternalSymbolMap) \ V(Map, external_symbol_with_ascii_data_map, ExternalSymbolWithAsciiDataMap) \ V(Map, external_ascii_symbol_map, ExternalAsciiSymbolMap) \ - V(Map, cons_string_map, ConsStringMap) \ - V(Map, cons_ascii_string_map, ConsAsciiStringMap) \ V(Map, external_string_map, ExternalStringMap) \ V(Map, external_string_with_ascii_data_map, ExternalStringWithAsciiDataMap) \ V(Map, external_ascii_string_map, ExternalAsciiStringMap) \
@@ -100,11 +107,6 @@
V(Map, proxy_map, ProxyMap) \ V(Object, nan_value, NanValue) \ V(Object, minus_zero_value, MinusZeroValue) \ - V(Object, instanceof_cache_function, InstanceofCacheFunction) \ - V(Object, instanceof_cache_map, InstanceofCacheMap) \ - V(Object, instanceof_cache_answer, InstanceofCacheAnswer) \ - V(String, empty_string, EmptyString) \ - V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \ V(Map, neander_map, NeanderMap) \ V(JSObject, message_listeners, MessageListeners) \ V(Proxy, prototype_accessors, PrototypeAccessors) \
@@ -113,8 +115,6 @@
V(Code, js_entry_code, JsEntryCode) \ V(Code, js_construct_entry_code, JsConstructEntryCode) \ V(Code, c_entry_code, CEntryCode) \ - V(FixedArray, number_string_cache, NumberStringCache) \ - V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ V(FixedArray, natives_source_cache, NativesSourceCache) \ V(Object, last_script_id, LastScriptId) \ V(Script, empty_script, EmptyScript) \
@@ -218,7 +218,6 @@
   V(KeyedLoadExternalArray_symbol, "KeyedLoadExternalArray")             \
   V(KeyedStoreExternalArray_symbol, "KeyedStoreExternalArray")

-
 // Forward declarations.
 class GCTracer;
 class HeapStats;
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Fri Mar 4 05:01:47 2011 +++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Mon Mar 7 00:35:19 2011
@@ -3561,8 +3561,7 @@

   // Set up the roots and smi constant registers.
   // Needs to be done before any further smi loads.
-  ExternalReference roots_address = ExternalReference::roots_address();
-  __ movq(kRootRegister, roots_address);
+  __ InitializeRootRegister();
   __ InitializeSmiConstantRegister();

 #ifdef ENABLE_LOGGING_AND_PROFILING
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Mar  2 03:45:31 2011
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Mar  7 00:35:19 2011
@@ -8217,7 +8217,8 @@
     // This is the map check instruction that will be patched (so we can't
     // use the double underscore macro that may insert instructions).
     // Initially use an invalid map to force a failure.
-    masm()->Move(kScratchRegister, Factory::null_value());
+    masm()->movq(kScratchRegister, Factory::null_value(),
+                 RelocInfo::EMBEDDED_OBJECT);
     masm()->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
                  kScratchRegister);
     // This branch is always a forwards branch so it's always a fixed
@@ -8293,7 +8294,8 @@
     // the __ macro for the following two instructions because it
     // might introduce extra instructions.
     __ bind(&patch_site);
-    masm()->Move(kScratchRegister, Factory::null_value());
+    masm()->movq(kScratchRegister, Factory::null_value(),
+                 RelocInfo::EMBEDDED_OBJECT);
     masm()->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
                  kScratchRegister);
     // This branch is always a forwards branch so it's always a fixed size
=======================================
--- /branches/bleeding_edge/src/x64/deoptimizer-x64.cc Fri Mar 4 04:34:05 2011 +++ /branches/bleeding_edge/src/x64/deoptimizer-x64.cc Mon Mar 7 00:35:19 2011
@@ -749,11 +749,8 @@

   // Set up the roots register.
   ExternalReference roots_address = ExternalReference::roots_address();
-  __ movq(r13, roots_address);
-
-  __ movq(kSmiConstantRegister,
- reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
-          RelocInfo::NONE);
+  __ InitializeRootRegister();
+  __ InitializeSmiConstantRegister();

   // Return to the continuation point.
   __ ret(0);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Mar 3 08:09:52 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Mar 7 00:35:19 2011
@@ -1432,7 +1432,7 @@
     __ j(equal, &load);
     __ movl(result, Immediate(Heap::kFalseValueRootIndex));
     __ bind(&load);
-    __ movq(result, Operand(kRootRegister, result, times_pointer_size, 0));
+    __ LoadRootIndexed(result, result, 0);
   } else {
     NearLabel true_value, false_value, done;
     __ j(equal, &true_value);
@@ -1563,8 +1563,7 @@
   }
   // result is zero if input is a smi, and one otherwise.
   ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
-  __ movq(result, Operand(kRootRegister, result, times_pointer_size,
-                          Heap::kTrueValueRootIndex * kPointerSize));
+  __ LoadRootIndexed(result, result, Heap::kTrueValueRootIndex);
 }


=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Mar 3 03:49:03 2011 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon Mar 7 00:35:19 2011
@@ -49,22 +49,35 @@


void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
-  movq(destination, Operand(kRootRegister, index << kPointerSizeLog2));
+  movq(destination, Operand(kRootRegister,
+ (index << kPointerSizeLog2) - kRootRegisterBias));
+}
+
+
+void MacroAssembler::LoadRootIndexed(Register destination,
+                                     Register variable_offset,
+                                     int fixed_offset) {
+  movq(destination,
+       Operand(kRootRegister,
+               variable_offset, times_pointer_size,
+               (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
 }


void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) {
-  movq(Operand(kRootRegister, index << kPointerSizeLog2), source);
+ movq(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias),
+       source);
 }


 void MacroAssembler::PushRoot(Heap::RootListIndex index) {
-  push(Operand(kRootRegister, index << kPointerSizeLog2));
+ push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
 }


void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
-  cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2));
+  cmpq(with, Operand(kRootRegister,
+                     (index << kPointerSizeLog2) - kRootRegisterBias));
 }


=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Fri Feb 25 05:22:38 2011 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon Mar 7 00:35:19 2011
@@ -52,6 +52,9 @@
 static const Register kRootRegister = { 13 };         // r13 (callee save).
 // Value of smi in kSmiConstantRegister.
 static const int kSmiConstantRegisterValue = 1;
+// Actual value of root register is offset from the root array's start
+// to take advantage of negitive 8-bit displacement values.
+static const int kRootRegisterBias = 128;

 // Convenience for platform-independent signatures.
 typedef Operand MemOperand;
@@ -74,6 +77,12 @@
   MacroAssembler(void* buffer, int size);

   void LoadRoot(Register destination, Heap::RootListIndex index);
+  // Load a root value where the index (or part of it) is variable.
+  // The variable_offset register is added to the fixed_offset value
+  // to get the index into the root-array.
+  void LoadRootIndexed(Register destination,
+                       Register variable_offset,
+                       int fixed_offset);
   void CompareRoot(Register with, Heap::RootListIndex index);
   void CompareRoot(const Operand& with, Heap::RootListIndex index);
   void PushRoot(Heap::RootListIndex index);
@@ -176,6 +185,12 @@
   void StoreToSafepointRegisterSlot(Register dst, Register src);
   void LoadFromSafepointRegisterSlot(Register dst, Register src);

+  void InitializeRootRegister() {
+    ExternalReference roots_address = ExternalReference::roots_address();
+    movq(kRootRegister, roots_address);
+    addq(kRootRegister, Immediate(kRootRegisterBias));
+  }
+
// ---------------------------------------------------------------------------
   // JavaScript invokes

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to