2010-04-26: Version 2.2.5
Various performance improvements (especially for ARM and x64)
Fixed bug in CPU profiling (http://crbug.com/42137)
Fixed a bug with the natives cache.
Fixed two bugs in the ARM code generator that can cause wrong calculations.
Fixed a bug that may cause a wrong result for shift operations.
git-svn-id: http://v8.googlecode.com/svn/trunk@4498 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 62365ff..10ccf9c 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -194,36 +194,34 @@
__ CallRuntime(Runtime::kTraceExit, 1);
}
+#ifdef DEBUG
// Add a label for checking the size of the code used for returning.
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
-
- // Calculate the exact length of the return sequence and make sure that
- // the constant pool is not emitted inside of the return sequence.
- int num_parameters = scope()->num_parameters();
- int32_t sp_delta = (num_parameters + 1) * kPointerSize;
- int return_sequence_length = Assembler::kJSReturnSequenceLength;
- if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) {
- // Additional mov instruction generated.
- return_sequence_length++;
+#endif
+ // Make sure that the constant pool is not emitted inside of the return
+ // sequence.
+ { Assembler::BlockConstPoolScope block_const_pool(masm_);
+ // Here we use masm_-> instead of the __ macro to avoid the code coverage
+ // tool from instrumenting as we rely on the code size here.
+ int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
+ CodeGenerator::RecordPositions(masm_, position);
+ __ RecordJSReturn();
+ masm_->mov(sp, fp);
+ masm_->ldm(ia_w, sp, fp.bit() | lr.bit());
+ masm_->add(sp, sp, Operand(sp_delta));
+ masm_->Jump(lr);
}
- masm_->BlockConstPoolFor(return_sequence_length);
- CodeGenerator::RecordPositions(masm_, position);
- __ RecordJSReturn();
- __ mov(sp, fp);
- __ ldm(ia_w, sp, fp.bit() | lr.bit());
- __ add(sp, sp, Operand(sp_delta));
- __ Jump(lr);
-
+#ifdef DEBUG
// Check that the size of the code used for returning matches what is
- // expected by the debugger. The add instruction above is an addressing
- // mode 1 instruction where there are restrictions on which immediate values
- // can be encoded in the instruction and which immediate values requires
- // use of an additional instruction for moving the immediate to a temporary
- // register.
- ASSERT_EQ(return_sequence_length,
- masm_->InstructionsGeneratedSince(&check_exit_codesize));
+ // expected by the debugger. If the sp_delts above cannot be encoded in the
+ // add instruction the add will generate two instructions.
+ int return_sequence_length =
+ masm_->InstructionsGeneratedSince(&check_exit_codesize);
+ CHECK(return_sequence_length == Assembler::kJSReturnSequenceLength ||
+ return_sequence_length == Assembler::kJSReturnSequenceLength + 1);
+#endif
}
}
@@ -1594,10 +1592,9 @@
// Inline smi case if we are in a loop.
Label stub_call, done;
+ int count_value = expr->op() == Token::INC ? 1 : -1;
if (loop_depth() > 0) {
- __ add(r0, r0, Operand(expr->op() == Token::INC
- ? Smi::FromInt(1)
- : Smi::FromInt(-1)));
+ __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC);
__ b(vs, &stub_call);
// We could eliminate this smi check if we split the code at
// the first smi check before calling ToNumber.
@@ -1605,11 +1602,9 @@
__ b(eq, &done);
__ bind(&stub_call);
// Call stub. Undo operation first.
- __ sub(r0, r0, Operand(r1));
+ __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
}
- __ mov(r1, Operand(expr->op() == Token::INC
- ? Smi::FromInt(1)
- : Smi::FromInt(-1)));
+ __ mov(r1, Operand(Smi::FromInt(count_value)));
GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE, r1, r0);
__ CallStub(&stub);
__ bind(&done);