Commit cd04469f authored by lrn@chromium.org's avatar lrn@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7069 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3c51baa1
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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));
}
......
......@@ -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
......
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