Simplify EmitCallIC.

Move the identification of the corresponding StatsCounter where it belongs,
namely into the Code class. Use the null pattern to signal "no inlined Smi
code". Removed a few unused counters.
Review URL: http://codereview.chromium.org/7273066

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8470 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c4f28bf2
...@@ -92,17 +92,19 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -92,17 +92,19 @@ class JumpPatchSite BASE_EMBEDDED {
} }
void EmitPatchInfo() { void EmitPatchInfo() {
int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_); if (patch_site_.is_bound()) {
Register reg; int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
reg.set_code(delta_to_patch_site / kOff12Mask); Register reg;
__ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask); reg.set_code(delta_to_patch_site / kOff12Mask);
__ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
#ifdef DEBUG #ifdef DEBUG
info_emitted_ = true; info_emitted_ = true;
#endif #endif
} else {
__ nop(); // Signals no inlined code.
}
} }
bool is_bound() const { return patch_site_.is_bound(); }
private: private:
MacroAssembler* masm_; MacroAssembler* masm_;
Label patch_site_; Label patch_site_;
...@@ -860,7 +862,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -860,7 +862,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Record position before stub call for type feedback. // Record position before stub call for type feedback.
SetSourcePosition(clause->position()); SetSourcePosition(clause->position());
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
EmitCallIC(ic, &patch_site, clause->CompareId()); EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
patch_site.EmitPatchInfo();
__ cmp(r0, Operand(0)); __ cmp(r0, Operand(0));
__ b(ne, &next_test); __ b(ne, &next_test);
...@@ -1689,7 +1692,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1689,7 +1692,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call); __ bind(&stub_call);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
__ jmp(&done); __ jmp(&done);
__ bind(&smi_case); __ bind(&smi_case);
...@@ -1770,7 +1774,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1770,7 +1774,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) { OverwriteMode mode) {
__ pop(r1); __ pop(r1);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), NULL, expr->id()); JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
context()->Plug(r0); context()->Plug(r0);
} }
...@@ -3853,7 +3859,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3853,7 +3859,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
BinaryOpStub stub(Token::ADD, NO_OVERWRITE); BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
patch_site.EmitPatchInfo();
__ bind(&done); __ bind(&done);
// Store the value returned in r0. // Store the value returned in r0.
...@@ -4126,7 +4133,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -4126,7 +4133,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC. // Record position and call the compare IC.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op); Handle<Code> ic = CompareIC::GetUninitialized(op);
EmitCallIC(ic, &patch_site, expr->id()); EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
__ cmp(r0, Operand(0)); __ cmp(r0, Operand(0));
Split(cond, if_true, if_false, fall_through); Split(cond, if_true, if_false, fall_through);
...@@ -4192,62 +4200,12 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, ...@@ -4192,62 +4200,12 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
unsigned ast_id) { unsigned ast_id) {
ASSERT(mode == RelocInfo::CODE_TARGET || ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT); mode == RelocInfo::CODE_TARGET_CONTEXT);
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1, r1, r2);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1, r1, r2);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
default:
break;
}
if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
__ Call(ic, mode); __ Call(ic, mode);
} else { } else {
ASSERT(mode == RelocInfo::CODE_TARGET); ASSERT(mode == RelocInfo::CODE_TARGET);
mode = RelocInfo::CODE_TARGET_WITH_ID;
__ CallWithAstId(ic, mode, ast_id);
}
}
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
JumpPatchSite* patch_site,
unsigned ast_id) {
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1, r1, r2);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1, r1, r2);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
default:
break;
}
if (ast_id == kNoASTId) {
__ Call(ic, RelocInfo::CODE_TARGET);
} else {
__ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
} }
if (patch_site != NULL && patch_site->is_bound()) {
patch_site->EmitPatchInfo();
} else {
__ nop(); // Signals no inlined code.
}
} }
......
...@@ -541,13 +541,6 @@ class FullCodeGenerator: public AstVisitor { ...@@ -541,13 +541,6 @@ class FullCodeGenerator: public AstVisitor {
RelocInfo::Mode mode, RelocInfo::Mode mode,
unsigned ast_id); unsigned ast_id);
// Calling an IC stub with a patch site. Passing NULL for patch_site
// or non NULL patch_site which is not activated indicates no inlined smi code
// and emits a nop after the IC call.
void EmitCallIC(Handle<Code> ic,
JumpPatchSite* patch_site,
unsigned ast_id);
// Set fields in the stack frame. Offsets are the frame pointer relative // Set fields in the stack frame. Offsets are the frame pointer relative
// offsets defined in, e.g., StandardFrameConstants. // offsets defined in, e.g., StandardFrameConstants.
void StoreToFrameField(int frame_offset, Register value); void StoreToFrameField(int frame_offset, Register value);
......
...@@ -78,16 +78,18 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -78,16 +78,18 @@ class JumpPatchSite BASE_EMBEDDED {
} }
void EmitPatchInfo() { void EmitPatchInfo() {
int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_); if (patch_site_.is_bound()) {
ASSERT(is_int8(delta_to_patch_site)); int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
__ test(eax, Immediate(delta_to_patch_site)); ASSERT(is_int8(delta_to_patch_site));
__ test(eax, Immediate(delta_to_patch_site));
#ifdef DEBUG #ifdef DEBUG
info_emitted_ = true; info_emitted_ = true;
#endif #endif
} else {
__ nop(); // Signals no inlined code.
}
} }
bool is_bound() const { return patch_site_.is_bound(); }
private: private:
// jc will be patched with jz, jnc will become jnz. // jc will be patched with jz, jnc will become jnz.
void EmitJump(Condition cc, Label* target, Label::Distance distance) { void EmitJump(Condition cc, Label* target, Label::Distance distance) {
...@@ -827,7 +829,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -827,7 +829,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Record position before stub call for type feedback. // Record position before stub call for type feedback.
SetSourcePosition(clause->position()); SetSourcePosition(clause->position());
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
EmitCallIC(ic, &patch_site, clause->CompareId()); EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
patch_site.EmitPatchInfo();
__ test(eax, Operand(eax)); __ test(eax, Operand(eax));
__ j(not_equal, &next_test); __ j(not_equal, &next_test);
__ Drop(1); // Switch value is no longer needed. __ Drop(1); // Switch value is no longer needed.
...@@ -1629,7 +1632,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1629,7 +1632,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call); __ bind(&stub_call);
__ mov(eax, ecx); __ mov(eax, ecx);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear); __ jmp(&done, Label::kNear);
// Smi case. // Smi case.
...@@ -1712,8 +1716,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1712,8 +1716,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) { OverwriteMode mode) {
__ pop(edx); __ pop(edx);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
// NULL signals no inlined smi code. JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
EmitCallIC(stub.GetCode(), NULL, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
context()->Plug(eax); context()->Plug(eax);
} }
...@@ -3816,7 +3821,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3816,7 +3821,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(edx, eax); __ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1))); __ mov(eax, Immediate(Smi::FromInt(1)));
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
patch_site.EmitPatchInfo();
__ bind(&done); __ bind(&done);
// Store the value returned in eax. // Store the value returned in eax.
...@@ -4089,7 +4095,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -4089,7 +4095,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC. // Record position and call the compare IC.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op); Handle<Code> ic = CompareIC::GetUninitialized(op);
EmitCallIC(ic, &patch_site, expr->id()); EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
__ test(eax, Operand(eax)); __ test(eax, Operand(eax));
...@@ -4153,53 +4160,10 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, ...@@ -4153,53 +4160,10 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
unsigned ast_id) { unsigned ast_id) {
ASSERT(mode == RelocInfo::CODE_TARGET || ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT); mode == RelocInfo::CODE_TARGET_CONTEXT);
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(isolate()->counters()->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
break;
case Code::STORE_IC:
__ IncrementCounter(isolate()->counters()->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
default:
break;
}
__ call(ic, mode, ast_id); __ call(ic, mode, ast_id);
} }
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
JumpPatchSite* patch_site,
unsigned ast_id) {
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
__ call(ic, RelocInfo::CODE_TARGET, ast_id);
if (patch_site != NULL && patch_site->is_bound()) {
patch_site->EmitPatchInfo();
} else {
__ nop(); // Signals no inlined code.
}
}
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
__ mov(Operand(ebp, frame_offset), value); __ mov(Operand(ebp, frame_offset), value);
......
...@@ -101,16 +101,18 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -101,16 +101,18 @@ class JumpPatchSite BASE_EMBEDDED {
} }
void EmitPatchInfo() { void EmitPatchInfo() {
int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_); if (patch_site_.is_bound()) {
Register reg = Register::from_code(delta_to_patch_site / kImm16Mask); int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
__ andi(at, reg, delta_to_patch_site % kImm16Mask); Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
__ andi(at, reg, delta_to_patch_site % kImm16Mask);
#ifdef DEBUG #ifdef DEBUG
info_emitted_ = true; info_emitted_ = true;
#endif #endif
} else {
__ nop(); // Signals no inlined code.
}
} }
bool is_bound() const { return patch_site_.is_bound(); }
private: private:
MacroAssembler* masm_; MacroAssembler* masm_;
Label patch_site_; Label patch_site_;
...@@ -865,7 +867,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -865,7 +867,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Record position before stub call for type feedback. // Record position before stub call for type feedback.
SetSourcePosition(clause->position()); SetSourcePosition(clause->position());
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
EmitCallIC(ic, &patch_site, clause->CompareId()); EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
patch_site.EmitPatchInfo();
__ Branch(&next_test, ne, v0, Operand(zero_reg)); __ Branch(&next_test, ne, v0, Operand(zero_reg));
__ Drop(1); // Switch value is no longer needed. __ Drop(1); // Switch value is no longer needed.
...@@ -1693,7 +1696,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1693,7 +1696,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call); __ bind(&stub_call);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
__ jmp(&done); __ jmp(&done);
__ bind(&smi_case); __ bind(&smi_case);
...@@ -1774,7 +1778,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1774,7 +1778,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
__ mov(a0, result_register()); __ mov(a0, result_register());
__ pop(a1); __ pop(a1);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), NULL, expr->id()); JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
context()->Plug(v0); context()->Plug(v0);
} }
...@@ -3882,7 +3888,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3882,7 +3888,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
BinaryOpStub stub(Token::ADD, NO_OVERWRITE); BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
patch_site.EmitPatchInfo();
__ bind(&done); __ bind(&done);
// Store the value returned in v0. // Store the value returned in v0.
...@@ -4153,7 +4160,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -4153,7 +4160,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC. // Record position and call the compare IC.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op); Handle<Code> ic = CompareIC::GetUninitialized(op);
EmitCallIC(ic, &patch_site, expr->id()); EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
} }
...@@ -4217,62 +4225,12 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, ...@@ -4217,62 +4225,12 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
unsigned ast_id) { unsigned ast_id) {
ASSERT(mode == RelocInfo::CODE_TARGET || ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT); mode == RelocInfo::CODE_TARGET_CONTEXT);
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1, a1, a2);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1, a1, a2);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
default:
break;
}
if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
__ Call(ic, mode); __ Call(ic, mode);
} else { } else {
ASSERT(mode == RelocInfo::CODE_TARGET); ASSERT(mode == RelocInfo::CODE_TARGET);
mode = RelocInfo::CODE_TARGET_WITH_ID;
__ CallWithAstId(ic, mode, ast_id);
}
}
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
JumpPatchSite* patch_site,
unsigned ast_id) {
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1, a1, a2);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1, a1, a2);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1, a1, a2);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1, a1, a2);
default:
break;
}
if (ast_id == kNoASTId) {
__ Call(ic, RelocInfo::CODE_TARGET);
} else {
__ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
} }
if (patch_site != NULL && patch_site->is_bound()) {
patch_site->EmitPatchInfo();
} else {
__ nop(); // Signals no inlined code.
}
} }
......
...@@ -170,14 +170,10 @@ namespace internal { ...@@ -170,14 +170,10 @@ namespace internal {
SC(named_load_inline_field, V8.NamedLoadInlineFast) \ SC(named_load_inline_field, V8.NamedLoadInlineFast) \
SC(keyed_load_inline_generic, V8.KeyedLoadInlineGeneric) \ SC(keyed_load_inline_generic, V8.KeyedLoadInlineGeneric) \
SC(keyed_load_inline_fast, V8.KeyedLoadInlineFast) \ SC(keyed_load_inline_fast, V8.KeyedLoadInlineFast) \
SC(named_load_full, V8.NamedLoadFull) \
SC(keyed_load_full, V8.KeyedLoadFull) \
SC(keyed_store_inline_generic, V8.KeyedStoreInlineGeneric) \ SC(keyed_store_inline_generic, V8.KeyedStoreInlineGeneric) \
SC(keyed_store_inline_fast, V8.KeyedStoreInlineFast) \ SC(keyed_store_inline_fast, V8.KeyedStoreInlineFast) \
SC(named_store_inline_generic, V8.NamedStoreInlineGeneric) \ SC(named_store_inline_generic, V8.NamedStoreInlineGeneric) \
SC(named_store_inline_fast, V8.NamedStoreInlineFast) \ SC(named_store_inline_fast, V8.NamedStoreInlineFast) \
SC(keyed_store_full, V8.KeyedStoreFull) \
SC(named_store_full, V8.NamedStoreFull) \
SC(keyed_store_inline_miss, V8.KeyedStoreInlineMiss) \ SC(keyed_store_inline_miss, V8.KeyedStoreInlineMiss) \
SC(named_store_global_inline, V8.NamedStoreGlobalInline) \ SC(named_store_global_inline, V8.NamedStoreGlobalInline) \
SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \ SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \
......
...@@ -78,16 +78,18 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -78,16 +78,18 @@ class JumpPatchSite BASE_EMBEDDED {
} }
void EmitPatchInfo() { void EmitPatchInfo() {
int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_); if (patch_site_.is_bound()) {
ASSERT(is_int8(delta_to_patch_site)); int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
__ testl(rax, Immediate(delta_to_patch_site)); ASSERT(is_int8(delta_to_patch_site));
__ testl(rax, Immediate(delta_to_patch_site));
#ifdef DEBUG #ifdef DEBUG
info_emitted_ = true; info_emitted_ = true;
#endif #endif
} else {
__ nop(); // Signals no inlined code.
}
} }
bool is_bound() const { return patch_site_.is_bound(); }
private: private:
// jc will be patched with jz, jnc will become jnz. // jc will be patched with jz, jnc will become jnz.
void EmitJump(Condition cc, Label* target, Label::Distance near_jump) { void EmitJump(Condition cc, Label* target, Label::Distance near_jump) {
...@@ -822,7 +824,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -822,7 +824,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Record position before stub call for type feedback. // Record position before stub call for type feedback.
SetSourcePosition(clause->position()); SetSourcePosition(clause->position());
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
EmitCallIC(ic, &patch_site, clause->CompareId()); EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
patch_site.EmitPatchInfo();
__ testq(rax, rax); __ testq(rax, rax);
__ j(not_equal, &next_test); __ j(not_equal, &next_test);
...@@ -1636,7 +1639,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1636,7 +1639,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call); __ bind(&stub_call);
__ movq(rax, rcx); __ movq(rax, rcx);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear); __ jmp(&done, Label::kNear);
__ bind(&smi_case); __ bind(&smi_case);
...@@ -1683,8 +1687,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1683,8 +1687,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) { OverwriteMode mode) {
__ pop(rdx); __ pop(rdx);
BinaryOpStub stub(op, mode); BinaryOpStub stub(op, mode);
// NULL signals no inlined smi code. JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
EmitCallIC(stub.GetCode(), NULL, expr->id()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
context()->Plug(rax); context()->Plug(rax);
} }
...@@ -3795,7 +3800,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3795,7 +3800,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ movq(rdx, rax); __ movq(rdx, rax);
__ Move(rax, Smi::FromInt(1)); __ Move(rax, Smi::FromInt(1));
} }
EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
patch_site.EmitPatchInfo();
__ bind(&done); __ bind(&done);
// Store the value returned in rax. // Store the value returned in rax.
...@@ -4067,7 +4073,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { ...@@ -4067,7 +4073,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
// Record position and call the compare IC. // Record position and call the compare IC.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op); Handle<Code> ic = CompareIC::GetUninitialized(op);
EmitCallIC(ic, &patch_site, expr->id()); EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
__ testq(rax, rax); __ testq(rax, rax);
...@@ -4131,54 +4138,10 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, ...@@ -4131,54 +4138,10 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
unsigned ast_id) { unsigned ast_id) {
ASSERT(mode == RelocInfo::CODE_TARGET || ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT); mode == RelocInfo::CODE_TARGET_CONTEXT);
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
__ call(ic, mode, ast_id); __ call(ic, mode, ast_id);
} }
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
JumpPatchSite* patch_site,
unsigned ast_id) {
Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
__ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
__ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
__ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
__ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
__ call(ic, RelocInfo::CODE_TARGET, ast_id);
if (patch_site != NULL && patch_site->is_bound()) {
patch_site->EmitPatchInfo();
} else {
__ nop(); // Signals no inlined code.
}
}
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
ASSERT(IsAligned(frame_offset, kPointerSize)); ASSERT(IsAligned(frame_offset, kPointerSize));
__ movq(Operand(rbp, frame_offset), value); __ movq(Operand(rbp, frame_offset), value);
......
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