Optimize loads from root-array in X64.
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 7 Mar 2011 08:35:19 +0000 (08:35 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 7 Mar 2011 08:35:19 +0000 (08:35 +0000)
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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7069 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/heap.h
src/x64/code-stubs-x64.cc
src/x64/codegen-x64.cc
src/x64/deoptimizer-x64.cc
src/x64/lithium-codegen-x64.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h

index 163eb04..6aa8339 100644 (file)
@@ -49,7 +49,6 @@ namespace internal {
   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 @@ namespace internal {
   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 @@ namespace internal {
   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 @@ namespace internal {
   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 @@ namespace internal {
   V(KeyedLoadExternalArray_symbol, "KeyedLoadExternalArray")             \
   V(KeyedStoreExternalArray_symbol, "KeyedStoreExternalArray")
 
-
 // Forward declarations.
 class GCTracer;
 class HeapStats;
index 153241c..eb92978 100644 (file)
@@ -3561,8 +3561,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
 
   // 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
index ad114c2..fc4bc04 100644 (file)
@@ -8217,7 +8217,8 @@ Result CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
     // 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 @@ Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
     // 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
index 1a84a57..daa9128 100644 (file)
@@ -749,11 +749,8 @@ void Deoptimizer::EntryGenerator::Generate() {
 
   // 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);
index 1007784..f9b84da 100644 (file)
@@ -1432,7 +1432,7 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
     __ 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 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
   }
   // 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);
 }
 
 
index cdd96e2..b468e82 100644 (file)
@@ -49,22 +49,35 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
 
 
 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));
 }
 
 
index 4cf59c4..7a7f1a2 100644 (file)
@@ -52,6 +52,9 @@ static const Register kSmiConstantRegister = { 15 };  // r15 (callee save).
 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 @@ class MacroAssembler: public Assembler {
   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 @@ class MacroAssembler: public Assembler {
   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