Reviewers: danno,
Description:
Avoid patching code after the call to binary operation stub in optimized
code
This patch just adds a nop after the call to the binary operation stub in
optimized code to avoid the patching for the inlined smi case used in the
full
code generator to kick in if the next instruction generated by the lithium
code
generator should accidentially enable that. For calls generated by
CallCodeGeneric this was already handled on Intel platforms, but missing on
ARM.
On IA-32 I did also try to check for whether the code containing the call
was
optimized (patch below), but that caused regressions on some benchmarks.
diff --git src/ia32/ic-ia32.cc src/ia32/ic-ia32.cc
index 5f143b1..f70e208 100644
--- src/ia32/ic-ia32.cc
+++ src/ia32/ic-ia32.cc
@@ -1603,12 +1603,18 @@ void CompareIC::UpdateCaches(Handle<Object> x,
Handle<Object> y) {
// Activate inlined smi code.
if (previous_state == UNINITIALIZED) {
- PatchInlinedSmiCode(address());
+ PatchInlinedSmiCode(address(), isolate());
}
}
-void PatchInlinedSmiCode(Address address) {
+void PatchInlinedSmiCode(Address address, Isolate* isolate) {
+ // Never patch in optimized code.
+ Code* code = isolate->pc_to_code_cache()->GetCacheEntry(address)->code;
+ if (code->kind() == Code::OPTIMIZED_FUNCTION) {
+ return;
+ }
+
// The address of the instruction following the call.
Address test_instruction_address =
address + Assembler::kCallTargetAddressOffset;
diff --git src/ic.cc src/ic.cc
index f70f75a..62e79da 100644
--- src/ic.cc
+++ src/ic.cc
@@ -2384,7 +2384,7 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
// Activate inlined smi code.
if (previous_type == BinaryOpIC::UNINITIALIZED) {
- PatchInlinedSmiCode(ic.address());
+ PatchInlinedSmiCode(ic.address(), isolate);
}
}
diff --git src/ic.h src/ic.h
index 11c2e3a..9ef4b20 100644
--- src/ic.h
+++ src/ic.h
@@ -721,7 +721,7 @@ class CompareIC: public IC {
};
// Helper for BinaryOpIC and CompareIC.
-void PatchInlinedSmiCode(Address address);
+void PatchInlinedSmiCode(Address address, Isolate* isolate);
} } // namespace v8::internal
[email protected]
BUG=none
TEST=none
Please review this at http://codereview.chromium.org/7350015/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-codegen-arm.cc
M src/ia32/lithium-codegen-ia32.cc
M src/x64/lithium-codegen-x64.cc
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
ee36314209eb21a95e5c9b93a93ff3130ab0cef8..dc93aea3461da251a785470be020995d790024b0
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -551,6 +551,13 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
RecordPosition(pointers->position());
__ Call(code, mode);
RegisterLazyDeoptimization(instr, safepoint_mode);
+
+ // Signal that we don't inline smi code before these stubs in the
+ // optimizing code generator.
+ if (code->kind() == Code::BINARY_OP_IC ||
+ code->kind() == Code::COMPARE_IC) {
+ __ nop();
+ }
}
@@ -1506,6 +1513,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+ __ nop(); // Signals no inlined code.
}
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
2f1b88e78961fc384ce3451c160357fdf764a2e1..6293718f6253ca8e10bc2fe73f04b1a1435ad786
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1345,6 +1345,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+ __ nop(); // Signals no inlined code.
}
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
3ebdc7cee74efd841ad852c296cf5fb785fe5bd5..98667ce87e35070f7410da03248b62363a847a02
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1341,6 +1341,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
BinaryOpStub stub(instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+ __ nop(); // Signals no inlined code.
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev