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

Reply via email to