// 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.
// 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
__ 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);
}
public:
enum {
kInstrSize = 4,
+ kInstrSizeLog2 = 2,
kPCReadOffset = 8
};
}
+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.
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
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