Author: [EMAIL PROTECTED]
Date: Wed Dec 10 00:37:58 2008
New Revision: 956

Modified:
    branches/bleeding_edge/src/assembler-arm.h
    branches/bleeding_edge/src/codegen-arm.cc
    branches/bleeding_edge/src/constants-arm.h
    branches/bleeding_edge/src/macro-assembler-arm.cc
    branches/bleeding_edge/src/macro-assembler-arm.h
    branches/bleeding_edge/test/mjsunit/switch.js

Log:
Arm codegen could emit const pool in the middle of jump table.


Modified: branches/bleeding_edge/src/assembler-arm.h
==============================================================================
--- branches/bleeding_edge/src/assembler-arm.h  (original)
+++ branches/bleeding_edge/src/assembler-arm.h  Wed Dec 10 00:37:58 2008
@@ -672,6 +672,14 @@
    // Patch branch instruction at pos to branch to given branch target pos
    void target_at_put(int pos, int target_pos);

+  // Check if is time to emit a constant pool for pending reloc info  
entries
+  void CheckConstPool(bool force_emit, bool require_jump);
+
+  // Block the emission of the constant pool before pc_offset
+  void BlockConstPoolBefore(int pc_offset) {
+    if (no_const_pool_before_ < pc_offset) no_const_pool_before_ =  
pc_offset;
+  }
+
   private:
    // Code buffer:
    // The buffer into which code and relocation info are generated.
@@ -769,14 +777,6 @@

    // Record reloc info for current pc_
    void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
-
-  // Check if is time to emit a constant pool for pending reloc info  
entries
-  void CheckConstPool(bool force_emit, bool require_jump);
-
-  // Block the emission of the constant pool before pc_offset
-  void BlockConstPoolBefore(int pc_offset) {
-    if (no_const_pool_before_ < pc_offset) no_const_pool_before_ =  
pc_offset;
-  }
  };

  } }  // namespace v8::internal

Modified: branches/bleeding_edge/src/codegen-arm.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.cc   (original)
+++ branches/bleeding_edge/src/codegen-arm.cc   Wed Dec 10 00:37:58 2008
@@ -1347,15 +1347,7 @@
    __ b(ne, fail_label);
    __ cmp(r0, Operand(Smi::FromInt(range)));
    __ b(ge, fail_label);
-  __ add(pc, pc, Operand(r0, LSL, 2 - kSmiTagSize));
-  // One extra instruction offsets the table, so the table's start address  
is
-  // the pc-register at the above add.
-  __ stop("Unreachable: Switch table alignment");
-
-  // Table containing branch operations.
-  for (int i = 0; i < range; i++) {
-    __ b(case_targets[i]);
-  }
+  __ SmiJumpTable(r0, case_targets);

    GenerateFastCaseSwitchCases(node, case_labels);
  }

Modified: branches/bleeding_edge/src/constants-arm.h
==============================================================================
--- branches/bleeding_edge/src/constants-arm.h  (original)
+++ branches/bleeding_edge/src/constants-arm.h  Wed Dec 10 00:37:58 2008
@@ -129,6 +129,7 @@
   public:
    enum {
      kInstrSize = 4,
+    kInstrSizeLog2 = 2,
      kPCReadOffset = 8
    };


Modified: branches/bleeding_edge/src/macro-assembler-arm.cc
==============================================================================
--- branches/bleeding_edge/src/macro-assembler-arm.cc   (original)
+++ branches/bleeding_edge/src/macro-assembler-arm.cc   Wed Dec 10 00:37:58  
2008
@@ -176,6 +176,20 @@
  }


+void MacroAssembler::SmiJumpTable(Register index, Vector<Label*> targets) {
+  // Empty the const pool.
+  CheckConstPool(true, true);
+  add(pc, pc, Operand(index,
+                      LSL,
+                      assembler::arm::Instr::kInstrSizeLog2 -  
kSmiTagSize));
+  BlockConstPoolBefore(pc_offset() + (targets.length() + 1) *  
sizeof(Instr));
+  nop();  // Jump table alignment.
+  for (int i = 0; i < targets.length(); i++) {
+    b(targets[i]);
+  }
+}
+
+
  // Will clobber 4 registers: object, offset, scratch, ip.  The
  // register 'object' contains a heap object pointer.  The heap object
  // tag is shifted away.

Modified: branches/bleeding_edge/src/macro-assembler-arm.h
==============================================================================
--- branches/bleeding_edge/src/macro-assembler-arm.h    (original)
+++ branches/bleeding_edge/src/macro-assembler-arm.h    Wed Dec 10 00:37:58  
2008
@@ -87,7 +87,8 @@
    void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al);
    void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
    void Ret();
-
+  // Jumps to the label at the index given by the Smi in "index".
+  void SmiJumpTable(Register index, Vector<Label*> targets);

    // Sets the remembered set bit for [address+offset], where address is the
    // address of the heap object 'object'.  The address must be in the  
first 8K

Modified: branches/bleeding_edge/test/mjsunit/switch.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/switch.js       (original)
+++ branches/bleeding_edge/test/mjsunit/switch.js       Wed Dec 10 00:37:58 2008
@@ -267,3 +267,23 @@
  assertEquals("default", f7(-(1<<30)-1), "0-1-switch.minsmi--");
  assertEquals("A", f7((170/16)-(170%16/16)), "0-1-switch.heapnum");

+
+function makeVeryLong(length) {
+  var res = "function() {\n" +
+            "  var res = 0;\n" +
+            "  for (var i = 0; i <= " + length + "; i++) {\n" +
+            "    switch(i) {\n";
+  for (var i = 0; i < length; i++) {
+    res += "    case " + i + ": res += 2; break;\n";
+  }
+  res += "    default: res += 1;\n" +
+         "    }\n" +
+         "  }\n" +
+         "  return res;\n" +
+         "}";
+  return eval(res);
+}
+var verylong_size = 1000;
+var verylong = makeVeryLong(verylong_size);
+
+assertEquals(verylong_size * 2 + 1, verylong());
\ No newline at end of file

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to