Commit daf1ea39 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Avoid constant pool blocking for too long

The generation of the deferred code for named property load where the load was inlined did a constant pool blocking for the whole deferred code. Having large numbers of this type of deferred code generated one ofter the other effectively blocked the constant pool for all the deferred code causing 

Removed the BeforeGenerate/AfterGenerate for the deferred code and made macro assembler StartBlockConstPool/EndBlockConstPool non-public. Re-introduced BlockConstPoolFor instead to use with BlockConstPoolScope to block some more instructions cross function calls.

Also handle the use of native code counters for inlined named property load.
Review URL: http://codereview.chromium.org/1787005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4507 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e35fbc93
......@@ -1784,6 +1784,11 @@ bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) {
}
void Assembler::BlockConstPoolFor(int instructions) {
BlockConstPoolBefore(pc_offset() + instructions * kInstrSize);
}
// Debugging.
void Assembler::RecordJSReturn() {
WriteRecordedPositions();
......
......@@ -941,6 +941,10 @@ class Assembler : public Malloced {
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
};
// Postpone the generation of the constant pool for the specified number of
// instructions.
void BlockConstPoolFor(int instructions);
// Debugging
// Mark address of the ExitJSFrame code.
......@@ -958,13 +962,6 @@ class Assembler : public Malloced {
int current_position() const { return current_position_; }
int current_statement_position() const { return current_statement_position_; }
void StartBlockConstPool() {
const_pool_blocked_nesting_++;
}
void EndBlockConstPool() {
const_pool_blocked_nesting_--;
}
// Read/patch instructions
static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
static void instr_at_put(byte* pc, Instr instr) {
......@@ -1001,6 +998,13 @@ class Assembler : public Malloced {
if (no_const_pool_before_ < pc_offset) no_const_pool_before_ = pc_offset;
}
void StartBlockConstPool() {
const_pool_blocked_nesting_++;
}
void EndBlockConstPool() {
const_pool_blocked_nesting_--;
}
private:
// Code buffer:
// The buffer into which code and relocation info are generated.
......
......@@ -351,17 +351,17 @@ void CodeGenerator::Generate(CompilationInfo* info) {
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. 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);
// Check that the size of the code used for returning matches what is
// 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.
......@@ -5230,34 +5230,34 @@ class DeferredReferenceGetNamedValue: public DeferredCode {
set_comment("[ DeferredReferenceGetNamedValue");
}
virtual void BeforeGenerate();
virtual void Generate();
virtual void AfterGenerate();
private:
Handle<String> name_;
};
void DeferredReferenceGetNamedValue::BeforeGenerate() {
__ StartBlockConstPool();
}
void DeferredReferenceGetNamedValue::Generate() {
__ DecrementCounter(&Counters::named_load_inline, 1, r1, r2);
__ IncrementCounter(&Counters::named_load_inline_miss, 1, r1, r2);
// Setup the name register and call load IC.
__ mov(r2, Operand(name_));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop(1) instruction to indicate that the
// inobject has been inlined.
__ nop(NAMED_PROPERTY_LOAD_INLINED);
}
// The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop(1) instruction to indicate that the
// in-object has been inlined.
__ nop(NAMED_PROPERTY_LOAD_INLINED);
void DeferredReferenceGetNamedValue::AfterGenerate() {
__ EndBlockConstPool();
// Block the constant pool for one more instruction after leaving this
// constant pool block scope to include the branch instruction ending the
// deferred code.
__ BlockConstPoolFor(1);
}
}
......@@ -5276,6 +5276,11 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
DeferredReferenceGetNamedValue* deferred =
new DeferredReferenceGetNamedValue(name);
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
__ IncrementCounter(&Counters::named_load_inline, 1,
frame_->scratch0(), frame_->scratch1());
// The following instructions are the inlined load of an in-object property.
// Parts of this code is patched, so the exact instructions generated needs
// to be fixed. Therefore the instruction pool is blocked when generating
......@@ -5303,13 +5308,12 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
// Use initially use an invalid index. The index will be patched by the
// inline cache code.
__ ldr(r0, MemOperand(r1, 0));
}
// Make sure that the expected number of instructions are generated.
ASSERT_EQ(kInlinedNamedLoadInstructions,
masm_->InstructionsGeneratedSince(&check_inlined_codesize));
// Make sure that the expected number of instructions are generated.
ASSERT_EQ(kInlinedNamedLoadInstructions,
masm_->InstructionsGeneratedSince(&check_inlined_codesize));
}
__ IncrementCounter(&Counters::named_load_inline, 1, r1, r2);
deferred->BindExit();
}
}
......
......@@ -77,13 +77,11 @@ void CodeGenerator::ProcessDeferred() {
}
// Generate the code.
Comment cmnt(masm_, code->comment());
code->BeforeGenerate();
masm_->bind(code->entry_label());
code->SaveRegisters();
code->Generate();
code->RestoreRegisters();
masm_->jmp(code->exit_label());
code->AfterGenerate();
}
}
......
......@@ -212,9 +212,6 @@ class DeferredCode: public ZoneObject {
void SaveRegisters();
void RestoreRegisters();
virtual void BeforeGenerate() { }
virtual void AfterGenerate() { }
protected:
MacroAssembler* masm_;
......
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