Commit ea42869a authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

ARM microoptimizations to megamorphic stub probing.

Review URL: https://chromiumcodereview.appspot.com/9323002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10591 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0d8ec7cd
......@@ -45,6 +45,7 @@ static void ProbeTable(Isolate* isolate,
StubCache::Table table,
Register name,
Register offset,
int offset_shift_bits,
Register scratch,
Register scratch2) {
ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
......@@ -63,23 +64,34 @@ static void ProbeTable(Isolate* isolate,
// Check that the key in the entry matches the name.
__ mov(offsets_base_addr, Operand(key_offset));
__ ldr(ip, MemOperand(offsets_base_addr, offset, LSL, 1));
__ ldr(ip, MemOperand(offsets_base_addr, offset, LSL, 1 + offset_shift_bits));
__ cmp(name, ip);
__ b(ne, &miss);
// Get the code entry from the cache.
__ add(offsets_base_addr, offsets_base_addr,
Operand(value_off_addr - key_off_addr));
__ ldr(scratch2, MemOperand(offsets_base_addr, offset, LSL, 1));
__ ldr(scratch2,
MemOperand(offsets_base_addr, offset, LSL, 1 + offset_shift_bits));
// Check that the flags match what we're looking for.
__ ldr(scratch2, FieldMemOperand(scratch2, Code::kFlagsOffset));
__ bic(scratch2, scratch2, Operand(Code::kFlagsNotUsedInLookup));
// It's a nice optimization if this constant is encodable in the bic insn.
uint32_t mask = Code::kFlagsNotUsedInLookup;
ASSERT(__ ImmediateFitsAddrMode1Instruction(mask));
__ bic(scratch2, scratch2, Operand(mask));
// Using cmn and the negative instead of cmp means we can use movw.
if (flags < 0) {
__ cmn(scratch2, Operand(-flags));
} else {
__ cmp(scratch2, Operand(flags));
}
__ b(ne, &miss);
// Re-load code entry from cache.
__ ldr(offset, MemOperand(offsets_base_addr, offset, LSL, 1));
__ ldr(offset,
MemOperand(offsets_base_addr, offset, LSL, 1 + offset_shift_bits));
// Jump to the first instruction in the code stub.
__ add(offset, offset, Operand(Code::kHeaderSize - kHeapObjectTag));
......@@ -189,23 +201,39 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
__ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset));
__ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset));
__ add(scratch, scratch, Operand(ip));
__ eor(scratch, scratch, Operand(flags));
__ and_(scratch,
scratch,
Operand((kPrimaryTableSize - 1) << kHeapObjectTagSize));
uint32_t mask = (kPrimaryTableSize - 1) << kHeapObjectTagSize;
// Mask down the eor argument to the minimum to keep the immediate
// ARM-encodable.
__ eor(scratch, scratch, Operand(flags & mask));
// Prefer ubfx to and_ here because the mask is not ARM-encodable.
__ Ubfx(scratch, scratch, kHeapObjectTagSize, kPrimaryTableBits);
// Probe the primary table.
ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra, extra2);
ProbeTable(isolate,
masm,
flags,
kPrimary,
name,
scratch,
kHeapObjectTagSize,
extra,
extra2);
// Primary miss: Compute hash for secondary probe.
__ sub(scratch, scratch, Operand(name));
__ rsb(scratch, name, Operand(scratch, LSL, kHeapObjectTagSize));
__ add(scratch, scratch, Operand(flags));
__ and_(scratch,
scratch,
Operand((kSecondaryTableSize - 1) << kHeapObjectTagSize));
__ Ubfx(scratch, scratch, kHeapObjectTagSize, kSecondaryTableBits);
// Probe the secondary table.
ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra, extra2);
ProbeTable(isolate,
masm,
flags,
kSecondary,
name,
scratch,
kHeapObjectTagSize,
extra,
extra2);
// Cache miss: Fall-through and let caller handle the miss by
// entering the runtime system.
......
......@@ -4364,8 +4364,8 @@ class Code: public HeapObject {
// Flags layout. BitField<type, shift, size>.
class ICStateField: public BitField<InlineCacheState, 0, 3> {};
class TypeField: public BitField<PropertyType, 3, 4> {};
class KindField: public BitField<Kind, 7, 4> {};
class CacheHolderField: public BitField<InlineCacheHolderFlag, 11, 1> {};
class CacheHolderField: public BitField<InlineCacheHolderFlag, 7, 1> {};
class KindField: public BitField<Kind, 8, 4> {};
class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
class IsPregeneratedField: public BitField<bool, 14, 1> {};
......@@ -4373,6 +4373,7 @@ class Code: public HeapObject {
static const int kArgumentsCountShift = 15;
static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
// This constant should be encodable in an ARM instruction.
static const int kFlagsNotUsedInLookup =
TypeField::kMask | CacheHolderField::kMask;
......
......@@ -343,8 +343,10 @@ class StubCache {
reinterpret_cast<Address>(table) + (offset << shift_amount));
}
static const int kPrimaryTableSize = 2048;
static const int kSecondaryTableSize = 512;
static const int kPrimaryTableBits = 11;
static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
static const int kSecondaryTableBits = 9;
static const int kSecondaryTableSize = (1 << kSecondaryTableBits);
Entry primary_[kPrimaryTableSize];
Entry secondary_[kSecondaryTableSize];
......
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