Reviewers: Mads Ager,
Description:
ARM: Reduce amount of code generated for LoadIC_Megamorphic.
BUG=none
TEST=none
Please review this at http://codereview.chromium.org/7210057/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/arm/assembler-arm.h
M src/arm/assembler-arm.cc
M src/arm/ic-arm.cc
M src/arm/stub-cache-arm.cc
M src/ia32/stub-cache-ia32.cc
M src/stub-cache.h
M src/x64/stub-cache-x64.cc
Index: src/arm/assembler-arm.cc
===================================================================
--- src/arm/assembler-arm.cc (revision 8507)
+++ src/arm/assembler-arm.cc (working copy)
@@ -2408,6 +2408,19 @@
}
+int Assembler::NumRegistersInRegList(RegList list) {
+ ASSERT((list & ((1 << kNumRegisters) - 1)) == list);
+ ASSERT(static_cast<size_t>(kNumRegisters) <= sizeof(RegList) * 8);
+ int numregs = 0;
+ for (int i = 0; i < kNumRegisters; i++) {
+ if (list & (1 << i)) {
+ numregs++;
+ }
+ }
+ return numregs;
+}
+
+
// Debugging.
void Assembler::RecordJSReturn() {
positions_recorder()->WriteRecordedPositions();
Index: src/arm/assembler-arm.h
===================================================================
--- src/arm/assembler-arm.h (revision 8507)
+++ src/arm/assembler-arm.h (working copy)
@@ -1226,6 +1226,7 @@
static Register GetCmpImmediateRegister(Instr instr);
static int GetCmpImmediateRawImmediate(Instr instr);
static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
+ static int NumRegistersInRegList(RegList list);
// Constants in pools are accessed via pc relative addressing, which can
// reach +/-4KB thereby defining a maximum distance between the
instruction
Index: src/arm/ic-arm.cc
===================================================================
--- src/arm/ic-arm.cc (revision 8507)
+++ src/arm/ic-arm.cc (working copy)
@@ -494,7 +494,7 @@
NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(
- masm, flags, r1, r2, r3, r4, r5);
+ masm, flags, r1, r2, r3, r4, r5, r6);
// If the stub cache probing failed, the receiver might be a value.
// For value objects, we use the map of the prototype objects for
@@ -533,7 +533,7 @@
// Probe the stub cache for the value object.
__ bind(&probe);
Isolate::Current()->stub_cache()->GenerateProbe(
- masm, flags, r1, r2, r3, r4, r5);
+ masm, flags, r1, r2, r3, r4, r5, r6);
__ bind(&miss);
}
@@ -833,7 +833,7 @@
NOT_IN_LOOP,
MONOMORPHIC);
Isolate::Current()->stub_cache()->GenerateProbe(
- masm, flags, r0, r2, r3, r4, r5);
+ masm, flags, r0, r2, r3, r4, r5, r6);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
@@ -1481,7 +1481,7 @@
strict_mode);
Isolate::Current()->stub_cache()->GenerateProbe(
- masm, flags, r1, r2, r3, r4, r5);
+ masm, flags, r1, r2, r3, r4, r5, r6);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
Index: src/arm/stub-cache-arm.cc
===================================================================
--- src/arm/stub-cache-arm.cc (revision 8507)
+++ src/arm/stub-cache-arm.cc (working copy)
@@ -41,7 +41,7 @@
static void ProbeTable(Isolate* isolate,
MacroAssembler* masm,
- Code::Flags flags,
+ Register flags,
StubCache::Table table,
Register name,
Register offset,
@@ -63,14 +63,13 @@
// 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, PreIndex));
__ 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,
+ value_off_addr - key_off_addr));
// Check that the flags match what we're looking for.
__ ldr(scratch2, FieldMemOperand(scratch2, Code::kFlagsOffset));
@@ -79,7 +78,7 @@
__ b(ne, &miss);
// Re-load code entry from cache.
- __ ldr(offset, MemOperand(offsets_base_addr, offset, LSL, 1));
+ __ ldr(offset, MemOperand(offsets_base_addr, value_off_addr -
key_off_addr));
// Jump to the first instruction in the code stub.
__ add(offset, offset, Operand(Code::kHeaderSize - kHeapObjectTag));
@@ -161,7 +160,8 @@
Register name,
Register scratch,
Register extra,
- Register extra2) {
+ Register extra2,
+ Register extra3) {
Isolate* isolate = masm->isolate();
Label miss;
@@ -172,46 +172,37 @@
// Make sure the flags does not name a specific type.
ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
- // Make sure that there are no register conflicts.
- ASSERT(!scratch.is(receiver));
- ASSERT(!scratch.is(name));
- ASSERT(!extra.is(receiver));
- ASSERT(!extra.is(name));
- ASSERT(!extra.is(scratch));
- ASSERT(!extra2.is(receiver));
- ASSERT(!extra2.is(name));
- ASSERT(!extra2.is(scratch));
- ASSERT(!extra2.is(extra));
+ // Make sure that there are no register conflicts and registers are
valid.
+ ASSERT(Assembler::NumRegistersInRegList(receiver.bit() | name.bit() |
+ scratch.bit() | extra.bit() | extra2.bit() | extra3.bit()) == 6);
- // Check scratch, extra and extra2 registers are valid.
- ASSERT(!scratch.is(no_reg));
- ASSERT(!extra.is(no_reg));
- ASSERT(!extra2.is(no_reg));
-
// Check that the receiver isn't a smi.
__ JumpIfSmi(receiver, &miss);
+ // Copy flags into a register.
+ __ mov(extra3, Operand(flags));
+
// Get the map of the receiver and compute the hash.
__ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset));
__ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset));
__ add(scratch, scratch, Operand(ip));
- __ eor(scratch, scratch, Operand(flags));
+ __ eor(scratch, scratch, Operand(extra3));
__ and_(scratch,
scratch,
Operand((kPrimaryTableSize - 1) << kHeapObjectTagSize));
// Probe the primary table.
- ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra, extra2);
+ ProbeTable(isolate, masm, extra3, kPrimary, name, scratch, extra,
extra2);
// Primary miss: Compute hash for secondary probe.
__ sub(scratch, scratch, Operand(name));
- __ add(scratch, scratch, Operand(flags));
+ __ add(scratch, scratch, Operand(extra3));
__ and_(scratch,
scratch,
Operand((kSecondaryTableSize - 1) << kHeapObjectTagSize));
// Probe the secondary table.
- ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra,
extra2);
+ ProbeTable(isolate, masm, extra3, kSecondary, name, scratch, extra,
extra2);
// Cache miss: Fall-through and let caller handle the miss by
// entering the runtime system.
Index: src/ia32/stub-cache-ia32.cc
===================================================================
--- src/ia32/stub-cache-ia32.cc (revision 8507)
+++ src/ia32/stub-cache-ia32.cc (working copy)
@@ -164,7 +164,8 @@
Register name,
Register scratch,
Register extra,
- Register extra2) {
+ Register extra2,
+ Register extra3) {
Isolate* isolate = Isolate::Current();
Label miss;
USE(extra2); // The register extra2 is not used on the ia32 platform.
@@ -183,9 +184,10 @@
ASSERT(!extra.is(name));
ASSERT(!extra.is(scratch));
- // Check scratch and extra registers are valid, and extra2 is unused.
+ // Check scratch is valid, extra2 and extra3 are unused.
ASSERT(!scratch.is(no_reg));
ASSERT(extra2.is(no_reg));
+ ASSERT(extra3.is(no_reg));
// Check that the receiver isn't a smi.
__ JumpIfSmi(receiver, &miss);
Index: src/stub-cache.h
===================================================================
--- src/stub-cache.h (revision 8507)
+++ src/stub-cache.h (working copy)
@@ -307,7 +307,8 @@
Register name,
Register scratch,
Register extra,
- Register extra2 = no_reg);
+ Register extra2 = no_reg,
+ Register extra3 = no_reg);
enum Table {
kPrimary,
Index: src/x64/stub-cache-x64.cc
===================================================================
--- src/x64/stub-cache-x64.cc (revision 8507)
+++ src/x64/stub-cache-x64.cc (working copy)
@@ -140,11 +140,13 @@
Register name,
Register scratch,
Register extra,
- Register extra2) {
+ Register extra2,
+ Register extra3) {
Isolate* isolate = masm->isolate();
Label miss;
USE(extra); // The register extra is not used on the X64 platform.
USE(extra2); // The register extra2 is not used on the X64 platform.
+ USE(extra3); // The register extra3 is not used on the X64 platform.
// Make sure that code is valid. The shifting code relies on the
// entry size being 16.
ASSERT(sizeof(Entry) == 16);
@@ -156,9 +158,10 @@
ASSERT(!scratch.is(receiver));
ASSERT(!scratch.is(name));
- // Check scratch register is valid, extra and extra2 are unused.
+ // Check scratch register is valid, extra, extra2 and extra3 are unused.
ASSERT(!scratch.is(no_reg));
ASSERT(extra2.is(no_reg));
+ ASSERT(extra3.is(no_reg));
// Check that the receiver isn't a smi.
__ JumpIfSmi(receiver, &miss);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev