diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index b129a6d485..39bb3ee4b6 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 df2b4cda2e..0c791b3493 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 4198ae79a1..566da4fa65 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 8c2a283873..1871e30259 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