Revision: 4456
Author: [email protected]
Date: Wed Apr 21 02:43:45 2010
Log: Use an object to control the blocking of the constant pool
Instead of indicating for how many instructions the constant pool needs to
be blocked the constant pool is now blocked while at least one instance of
ScopedConstPoolBlocker exists.
Review URL: http://codereview.chromium.org/1673006
http://code.google.com/p/v8/source/detail?r=4456
Modified:
/branches/bleeding_edge/src/arm/assembler-arm.cc
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Mar 23 06:38:04
2010
+++ /branches/bleeding_edge/src/arm/assembler-arm.cc Wed Apr 21 02:43:45
2010
@@ -306,6 +306,7 @@
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
num_prinfo_ = 0;
next_buffer_check_ = 0;
+ const_pool_blocked_nesting_ = 0;
no_const_pool_before_ = 0;
last_const_pool_end_ = 0;
last_bound_pos_ = 0;
@@ -1724,11 +1725,6 @@
uint32_t dummy2;
return fits_shifter(imm32, &dummy1, &dummy2, NULL);
}
-
-
-void Assembler::BlockConstPoolFor(int instructions) {
- BlockConstPoolBefore(pc_offset() + instructions * kInstrSize);
-}
// Debugging.
@@ -1894,12 +1890,17 @@
// However, some small sequences of instructions must not be broken up
by the
// insertion of a constant pool; such sequences are protected by setting
- // no_const_pool_before_, which is checked here. Also, recursive calls to
- // CheckConstPool are blocked by no_const_pool_before_.
- if (pc_offset() < no_const_pool_before_) {
+ // either const_pool_blocked_nesting_ or no_const_pool_before_, which are
+ // both checked here. Also, recursive calls to CheckConstPool are
blocked by
+ // no_const_pool_before_.
+ if (const_pool_blocked_nesting_ > 0 || pc_offset() <
no_const_pool_before_) {
// Emission is currently blocked; make sure we try again as soon as
// possible.
- next_buffer_check_ = no_const_pool_before_;
+ if (const_pool_blocked_nesting_ > 0) {
+ next_buffer_check_ = pc_offset() + kInstrSize;
+ } else {
+ next_buffer_check_ = no_const_pool_before_;
+ }
// Something is wrong if emission is forced and blocked at the same
time.
ASSERT(!force_emit);
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Wed Apr 21 00:32:04 2010
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Wed Apr 21 02:43:45 2010
@@ -925,9 +925,21 @@
// 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);
+ // Class for scoping postponing the constant pool generation.
+ class BlockConstPoolScope {
+ public:
+ explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
+ assem_->const_pool_blocked_nesting_++;
+ }
+ ~BlockConstPoolScope() {
+ assem_->const_pool_blocked_nesting_--;
+ }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
+
+ Assembler* assem_;
+ };
// Debugging
@@ -1022,8 +1034,9 @@
// distance between pools.
static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval;
- // Emission of the constant pool may be blocked in some code sequences
- int no_const_pool_before_; // block emission before this pc offset
+ // Emission of the constant pool may be blocked in some code sequences.
+ int const_pool_blocked_nesting_; // Block emission if this is not zero.
+ int no_const_pool_before_; // Block emission before this pc offset.
// Keep track of the last emitted pool to guarantee a maximal distance
int last_const_pool_end_; // pc offset following the last constant pool
@@ -1075,6 +1088,7 @@
friend class RegExpMacroAssemblerARM;
friend class RelocInfo;
friend class CodePatcher;
+ friend class BlockConstPoolScope;
};
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Thu Apr 15 07:06:57 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Wed Apr 21 02:43:45 2010
@@ -353,37 +353,37 @@
frame_->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.
- int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
- int return_sequence_length = Assembler::kJSReturnSequenceLength;
- 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.
- masm_->add(sp, sp, Operand(sp_delta));
- masm_->Jump(lr);
-
+#endif
+
+ {
+ // Make sure that the constant pool is not emitted inside of the
return
+ // sequence.
+ Assembler::BlockConstPoolScope block_const_pool(masm_);
+
+ // 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);
+ }
+
+#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
}
// Adjust for function-level loop nesting.
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Apr 19 05:39:07
2010
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Apr 21 02:43:45
2010
@@ -194,36 +194,37 @@
__ 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++;
- }
- 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);
-
+#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);
+ }
+
+#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
}
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Apr 15
02:34:47 2010
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Apr 21
02:43:45 2010
@@ -117,18 +117,20 @@
// ldr ip, [pc, #...]
// blx ip
- // The two instructions (ldr and blx) could be separated by a literal
- // pool and the code would still work. The issue comes from the
- // patching code which expect the ldr to be just above the blx.
- BlockConstPoolFor(2);
- // Statement positions are expected to be recorded when the target
- // address is loaded. The mov method will automatically record
- // positions when pc is the target, since this is not the case here
- // we have to do it explicitly.
- WriteRecordedPositions();
-
- mov(ip, Operand(target, rmode), LeaveCC, cond);
- blx(ip, cond);
+ {
+ // The two instructions (ldr and blx) could be separated by a constant
+ // pool and the code would still work. The issue comes from the
+ // patching code which expect the ldr to be just above the blx.
+ BlockConstPoolScope block_const_pool(this);
+ // Statement positions are expected to be recorded when the target
+ // address is loaded. The mov method will automatically record
+ // positions when pc is the target, since this is not the case here
+ // we have to do it explicitly.
+ WriteRecordedPositions();
+
+ mov(ip, Operand(target, rmode), LeaveCC, cond);
+ blx(ip, cond);
+ }
ASSERT(kCallTargetAddressOffset == 2 * kInstrSize);
#else
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev