From 77a71c90c7333d9418b8a0b10cf49feb737fafd8 Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Wed, 4 Nov 2009 14:45:50 +0000 Subject: [PATCH] Fix issue 491: constantpool dump violates ARM debugger assertion for return point The generation of the return sequence is now protected from having the constant pool emitted inside of it in both compilers. BUG=http://code.google.com/p/v8/issues/detail?id=491 TEST=test/mjsunit/regress/regress-491.js Review URL: http://codereview.chromium.org/362003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3215 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/assembler-arm.cc | 5 +++ src/arm/assembler-arm.h | 4 +++ src/arm/codegen-arm.cc | 20 ++++++------ src/arm/codegen-arm.h | 4 --- src/arm/debug-arm.cc | 2 +- src/arm/fast-codegen-arm.cc | 28 +++++++++-------- src/debug.h | 2 ++ test/mjsunit/regress/regress-491.js | 47 +++++++++++++++++++++++++++++ 8 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 test/mjsunit/regress/regress-491.js diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index b129a6d48..39bb3ee4b 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -1318,6 +1318,11 @@ bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) { } +void Assembler::BlockConstPoolFor(int instructions) { + BlockConstPoolBefore(pc_offset() + instructions * kInstrSize); +} + + // Debugging void Assembler::RecordJSReturn() { WriteRecordedPositions(); diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h index df2b4cda2..0c791b349 100644 --- a/src/arm/assembler-arm.h +++ b/src/arm/assembler-arm.h @@ -685,6 +685,10 @@ class Assembler : public Malloced { // Check whether an immediate fits an addressing mode 1 instruction. bool ImmediateFitsAddrMode1Instruction(int32_t imm32); + // Postpone the generation of the constant pool for the specified number of + // instructions. + void BlockConstPoolFor(int instructions); + // Debugging // Mark address of the ExitJSFrame code. diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 4198ae79a..566da4fa6 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -322,13 +322,22 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { 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. + int32_t sp_delta = (scope_->num_parameters() + 1) * kPointerSize; + int return_sequence_length = Debug::kARMJSReturnSequenceLength; + if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) { + // Additional mov instruction generated. + return_sequence_length++; + } + masm_->BlockConstPoolFor(return_sequence_length); + // Tear down the frame which will restore the caller's frame pointer and // the link register. frame_->Exit(); // 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; masm_->add(sp, sp, Operand(sp_delta)); masm_->Jump(lr); @@ -338,15 +347,8 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { // can be encoded in the instruction and which immediate values requires // use of an additional instruction for moving the immediate to a temporary // register. -#ifdef DEBUG - int expected_return_sequence_length = kJSReturnSequenceLength; - if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) { - // Additional mov instruction generated. - expected_return_sequence_length++; - } - ASSERT_EQ(expected_return_sequence_length, + ASSERT_EQ(return_sequence_length, masm_->InstructionsGeneratedSince(&check_exit_codesize)); -#endif } // Code generation state must be reset. diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h index 8c2a28387..1871e3025 100644 --- a/src/arm/codegen-arm.h +++ b/src/arm/codegen-arm.h @@ -187,10 +187,6 @@ class CodeGenerator: public AstVisitor { static const int kUnknownIntValue = -1; - // Number of instructions used for the JS return sequence. The constant is - // used by the debugger to patch the JS return sequence. - static const int kJSReturnSequenceLength = 4; - private: // Construction/Destruction CodeGenerator(int buffer_size, Handle