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
-~----------~----~----~----~------~----~------~--~---