Commit 5afca497 authored by lrn@chromium.org's avatar lrn@chromium.org

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


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@956 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4f15a008
......@@ -672,6 +672,14 @@ class Assembler : public Malloced {
// 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 @@ class Assembler : public Malloced {
// 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
......
......@@ -1347,15 +1347,7 @@ void CodeGenerator::GenerateFastCaseSwitchJumpTable(
__ 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);
}
......
......@@ -129,6 +129,7 @@ class Instr {
public:
enum {
kInstrSize = 4,
kInstrSizeLog2 = 2,
kPCReadOffset = 8
};
......
......@@ -176,6 +176,20 @@ void MacroAssembler::Ret() {
}
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.
......
......@@ -87,7 +87,8 @@ class MacroAssembler: public Assembler {
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
......
......@@ -267,3 +267,23 @@ assertEquals("default", f7(1<<30), "0-1-switch.maxsmi++");
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment