Commit e418a1e4 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[ignition] Fix wide switch bytecodes' offsets

Bug: v8:6351
Bug: v8:6366
Change-Id: I3ec9bd75031b2c6148278353461f442c1eaf60ca
Reviewed-on: https://chromium-review.googlesource.com/506015
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45335}
parent 1972e373
...@@ -18,15 +18,15 @@ namespace interpreter { ...@@ -18,15 +18,15 @@ namespace interpreter {
class BytecodeArrayAccessor; class BytecodeArrayAccessor;
struct JumpTableTargetOffset { struct V8_EXPORT_PRIVATE JumpTableTargetOffset {
int case_value; int case_value;
int target_offset; int target_offset;
}; };
class JumpTableTargetOffsets final { class V8_EXPORT_PRIVATE JumpTableTargetOffsets final {
public: public:
// Minimal iterator implementation for use in ranged-for. // Minimal iterator implementation for use in ranged-for.
class iterator final { class V8_EXPORT_PRIVATE iterator final {
public: public:
iterator(int case_value, int table_offset, int table_end, iterator(int case_value, int table_offset, int table_end,
const BytecodeArrayAccessor* accessor); const BytecodeArrayAccessor* accessor);
......
...@@ -423,6 +423,10 @@ void BytecodeArrayWriter::EmitSwitch(BytecodeNode* node, ...@@ -423,6 +423,10 @@ void BytecodeArrayWriter::EmitSwitch(BytecodeNode* node,
DCHECK(Bytecodes::IsSwitch(node->bytecode())); DCHECK(Bytecodes::IsSwitch(node->bytecode()));
size_t current_offset = bytecodes()->size(); size_t current_offset = bytecodes()->size();
if (node->operand_scale() > OperandScale::kSingle) {
// Adjust for scaling byte prefix.
current_offset += 1;
}
jump_table->set_switch_bytecode_offset(current_offset); jump_table->set_switch_bytecode_offset(current_offset);
EmitBytecode(node); EmitBytecode(node);
......
...@@ -26,7 +26,6 @@ class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { ...@@ -26,7 +26,6 @@ class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode; using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;
TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
CanonicalHandleScope canonical(isolate());
BytecodeArrayBuilder builder(isolate(), zone(), 1, 1, 131); BytecodeArrayBuilder builder(isolate(), zone(), 1, 1, 131);
Factory* factory = isolate()->factory(); Factory* factory = isolate()->factory();
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(), AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
...@@ -434,7 +433,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -434,7 +433,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
CanonicalHandleScope canonical(isolate());
for (int locals = 0; locals < 5; locals++) { for (int locals = 0; locals < 5; locals++) {
for (int contexts = 0; contexts < 4; contexts++) { for (int contexts = 0; contexts < 4; contexts++) {
for (int temps = 0; temps < 3; temps++) { for (int temps = 0; temps < 3; temps++) {
...@@ -464,7 +462,6 @@ TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { ...@@ -464,7 +462,6 @@ TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
TEST_F(BytecodeArrayBuilderTest, RegisterValues) { TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
CanonicalHandleScope canonical(isolate());
int index = 1; int index = 1;
Register the_register(index); Register the_register(index);
...@@ -477,7 +474,6 @@ TEST_F(BytecodeArrayBuilderTest, RegisterValues) { ...@@ -477,7 +474,6 @@ TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
TEST_F(BytecodeArrayBuilderTest, Parameters) { TEST_F(BytecodeArrayBuilderTest, Parameters) {
CanonicalHandleScope canonical(isolate());
BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 0); BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 0);
Register receiver(builder.Receiver()); Register receiver(builder.Receiver());
...@@ -487,7 +483,6 @@ TEST_F(BytecodeArrayBuilderTest, Parameters) { ...@@ -487,7 +483,6 @@ TEST_F(BytecodeArrayBuilderTest, Parameters) {
TEST_F(BytecodeArrayBuilderTest, Constants) { TEST_F(BytecodeArrayBuilderTest, Constants) {
CanonicalHandleScope canonical(isolate());
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0); BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0);
AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(), AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
isolate()->heap()->HashSeed()); isolate()->heap()->HashSeed());
...@@ -514,7 +509,6 @@ TEST_F(BytecodeArrayBuilderTest, Constants) { ...@@ -514,7 +509,6 @@ TEST_F(BytecodeArrayBuilderTest, Constants) {
} }
TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
CanonicalHandleScope canonical(isolate());
static const int kFarJumpDistance = 256 + 20; static const int kFarJumpDistance = 256 + 20;
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1); BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1);
...@@ -632,7 +626,6 @@ TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { ...@@ -632,7 +626,6 @@ TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
CanonicalHandleScope canonical(isolate());
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1); BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1);
Register reg(0); Register reg(0);
...@@ -680,9 +673,103 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { ...@@ -680,9 +673,103 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
CHECK(iterator.done()); CHECK(iterator.done());
} }
TEST_F(BytecodeArrayBuilderTest, SmallSwitch) {
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1);
// Small jump table that fits into the single-size constant pool
int small_jump_table_size = 5;
int small_jump_table_base = -2;
BytecodeJumpTable* small_jump_table =
builder.AllocateJumpTable(small_jump_table_size, small_jump_table_base);
builder.LoadLiteral(Smi::FromInt(7)).SwitchOnSmiNoFeedback(small_jump_table);
for (int i = 0; i < small_jump_table_size; i++) {
builder.Bind(small_jump_table, small_jump_table_base + i).Debugger();
}
builder.Return();
Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
BytecodeArrayIterator iterator(array);
CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
{
int i = 0;
int switch_end =
iterator.current_offset() + iterator.current_bytecode_size();
for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
CHECK_EQ(entry.case_value, small_jump_table_base + i);
CHECK_EQ(entry.target_offset, switch_end + i);
i++;
}
CHECK_EQ(i, small_jump_table_size);
}
iterator.Advance();
for (int i = 0; i < small_jump_table_size; i++) {
CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
iterator.Advance();
}
CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
iterator.Advance();
CHECK(iterator.done());
}
TEST_F(BytecodeArrayBuilderTest, WideSwitch) {
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 1);
// Large jump table that requires a wide Switch bytecode.
int large_jump_table_size = 256;
int large_jump_table_base = -10;
BytecodeJumpTable* large_jump_table =
builder.AllocateJumpTable(large_jump_table_size, large_jump_table_base);
builder.LoadLiteral(Smi::FromInt(7)).SwitchOnSmiNoFeedback(large_jump_table);
for (int i = 0; i < large_jump_table_size; i++) {
builder.Bind(large_jump_table, large_jump_table_base + i).Debugger();
}
builder.Return();
Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
BytecodeArrayIterator iterator(array);
CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
iterator.Advance();
CHECK_EQ(iterator.current_bytecode(), Bytecode::kSwitchOnSmiNoFeedback);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
{
int i = 0;
int switch_end =
iterator.current_offset() + iterator.current_bytecode_size();
for (const auto& entry : iterator.GetJumpTableTargetOffsets()) {
CHECK_EQ(entry.case_value, large_jump_table_base + i);
CHECK_EQ(entry.target_offset, switch_end + i);
i++;
}
CHECK_EQ(i, large_jump_table_size);
}
iterator.Advance();
for (int i = 0; i < large_jump_table_size; i++) {
CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
iterator.Advance();
}
CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
iterator.Advance();
CHECK(iterator.done());
}
TEST_F(BytecodeArrayBuilderTest, LabelReuse) { TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
CanonicalHandleScope canonical(isolate());
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0); BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0);
// Labels can only have 1 forward reference, but // Labels can only have 1 forward reference, but
...@@ -715,7 +802,6 @@ TEST_F(BytecodeArrayBuilderTest, LabelReuse) { ...@@ -715,7 +802,6 @@ TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
CanonicalHandleScope canonical(isolate());
static const int kRepeats = 3; static const int kRepeats = 3;
BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0); BytecodeArrayBuilder builder(isolate(), zone(), 1, 0, 0);
......
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