- Revision
- 97025
- Author
- [email protected]
- Date
- 2011-10-09 03:19:23 -0700 (Sun, 09 Oct 2011)
Log Message
Fix value profiling in 32_64 JIT
https://bugs.webkit.org/show_bug.cgi?id=69717
Patch by Yuqiang Xian <[email protected]> on 2011-10-09
Reviewed by Filip Pizlo.
Current value profiling for 32_64 JIT is broken and cannot record
correct predicated types, which results in many speculation failures
in the 32_64 DFG JIT, fallbacks to baseline JIT, and re-optimizations
again and again.
With this fix 32_64 DFG JIT can demonstrate real performance gains.
* bytecode/ValueProfile.cpp:
(JSC::ValueProfile::computeStatistics):
* bytecode/ValueProfile.h:
(JSC::ValueProfile::classInfo):
(JSC::ValueProfile::numberOfSamples):
(JSC::ValueProfile::isLive):
(JSC::ValueProfile::numberOfInt32s):
(JSC::ValueProfile::numberOfDoubles):
(JSC::ValueProfile::numberOfBooleans):
(JSC::ValueProfile::dump):
Empty value check should be performed on decoded JSValue,
as for 32_64 empty value is not identical to encoded 0.
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITInlineMethods.h:
(JSC::JIT::emitValueProfilingSite):
* jit/JITStubCall.h:
(JSC::JITStubCall::callWithValueProfiling):
Record the right profiling result for 32_64.
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (97024 => 97025)
--- trunk/Source/_javascript_Core/ChangeLog 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-10-09 10:19:23 UTC (rev 97025)
@@ -1,5 +1,38 @@
2011-10-09 Yuqiang Xian <[email protected]>
+ Fix value profiling in 32_64 JIT
+ https://bugs.webkit.org/show_bug.cgi?id=69717
+
+ Reviewed by Filip Pizlo.
+
+ Current value profiling for 32_64 JIT is broken and cannot record
+ correct predicated types, which results in many speculation failures
+ in the 32_64 DFG JIT, fallbacks to baseline JIT, and re-optimizations
+ again and again.
+ With this fix 32_64 DFG JIT can demonstrate real performance gains.
+
+ * bytecode/ValueProfile.cpp:
+ (JSC::ValueProfile::computeStatistics):
+ * bytecode/ValueProfile.h:
+ (JSC::ValueProfile::classInfo):
+ (JSC::ValueProfile::numberOfSamples):
+ (JSC::ValueProfile::isLive):
+ (JSC::ValueProfile::numberOfInt32s):
+ (JSC::ValueProfile::numberOfDoubles):
+ (JSC::ValueProfile::numberOfBooleans):
+ (JSC::ValueProfile::dump):
+ Empty value check should be performed on decoded JSValue,
+ as for 32_64 empty value is not identical to encoded 0.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitValueProfilingSite):
+ * jit/JITStubCall.h:
+ (JSC::JITStubCall::callWithValueProfiling):
+ Record the right profiling result for 32_64.
+
+2011-10-09 Yuqiang Xian <[email protected]>
+
Remove 32 bit restrictions in DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=69711
Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (97024 => 97025)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp 2011-10-09 10:19:23 UTC (rev 97025)
@@ -60,7 +60,8 @@
void ValueProfile::computeStatistics(Statistics& statistics) const
{
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!m_buckets[i]) {
+ JSValue value = JSValue::decode(m_buckets[i]);
+ if (!value) {
WeakBucket weakBucket = m_weakBuckets[i];
if (!!weakBucket) {
statistics.samples++;
@@ -72,7 +73,6 @@
statistics.samples++;
- JSValue value = JSValue::decode(m_buckets[i]);
if (value.isInt32())
statistics.int32s++;
else if (value.isDouble())
Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (97024 => 97025)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2011-10-09 10:19:23 UTC (rev 97025)
@@ -55,8 +55,8 @@
const ClassInfo* classInfo(unsigned bucket) const
{
- if (!!m_buckets[bucket]) {
- JSValue value = JSValue::decode(m_buckets[bucket]);
+ JSValue value = JSValue::decode(m_buckets[bucket]);
+ if (!!value) {
if (!value.isCell())
return 0;
return value.asCell()->structure()->classInfo();
@@ -68,7 +68,7 @@
{
unsigned result = 0;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] || !!m_weakBuckets[i])
+ if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
result++;
}
return result;
@@ -82,7 +82,7 @@
bool isLive() const
{
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] || !!m_weakBuckets[i])
+ if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
return true;
}
return false;
@@ -99,7 +99,7 @@
{
unsigned result = 0;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isInt32())
+ if (JSValue::decode(m_buckets[i]).isInt32())
result++;
}
return result;
@@ -109,7 +109,7 @@
{
unsigned result = 0;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isDouble())
+ if (JSValue::decode(m_buckets[i]).isDouble())
result++;
}
return result;
@@ -170,7 +170,7 @@
{
unsigned result = 0;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isBoolean())
+ if (JSValue::decode(m_buckets[i]).isBoolean())
result++;
}
return result;
@@ -238,7 +238,8 @@
predictionToString(m_prediction), m_numberOfSamplesInPrediction);
bool first = true;
for (unsigned i = 0; i < numberOfBuckets; ++i) {
- if (!!m_buckets[i] || !!m_weakBuckets[i]) {
+ JSValue value = JSValue::decode(m_buckets[i]);
+ if (!!value || !!m_weakBuckets[i]) {
if (first) {
fprintf(out, ": ");
first = false;
@@ -246,8 +247,8 @@
fprintf(out, ", ");
}
- if (!!m_buckets[i])
- fprintf(out, "%s", JSValue::decode(m_buckets[i]).description());
+ if (!!value)
+ fprintf(out, "%s", value.description());
if (!!m_weakBuckets[i])
fprintf(out, "DeadCell");
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (97024 => 97025)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2011-10-09 10:19:23 UTC (rev 97025)
@@ -573,7 +573,12 @@
&& argumentRegister == -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters)
m_codeBlock->addValueProfile(-1);
else {
+#if USE(JSVALUE64)
loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0);
+#elif USE(JSVALUE32_64)
+ load32(Address(callFrameRegister, argumentRegister * sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ load32(Address(callFrameRegister, argumentRegister * sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+#endif
emitValueProfilingSite(FirstProfilingSite);
}
}
Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (97024 => 97025)
--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h 2011-10-09 10:19:23 UTC (rev 97025)
@@ -471,7 +471,13 @@
add32(Imm32(3), bucketCounterRegister);
and32(Imm32(ValueProfile::bucketIndexMask), bucketCounterRegister);
move(ImmPtr(valueProfile->m_buckets), scratch);
+#if USE(JSVALUE64)
storePtr(value, BaseIndex(scratch, bucketCounterRegister, TimesEight));
+#elif USE(JSVALUE32_64)
+ const RegisterID valueTag = regT1;
+ store32(value, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+ store32(valueTag, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+#endif
}
#endif
Modified: trunk/Source/_javascript_Core/jit/JITStubCall.h (97024 => 97025)
--- trunk/Source/_javascript_Core/jit/JITStubCall.h 2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JITStubCall.h 2011-10-09 10:19:23 UTC (rev 97025)
@@ -205,6 +205,9 @@
{
ASSERT(m_returnType == Value || m_returnType == Cell);
JIT::Call call = this->call();
+ ASSERT(JIT::returnValueRegister == JIT::regT0);
+ if (m_returnType == Cell)
+ m_jit->move(JIT::TrustedImm32(JSValue::CellTag), JIT::regT1);
m_jit->emitValueProfilingSite(kind);
if (m_returnType == Value)
m_jit->emitStore(dst, JIT::regT1, JIT::regT0);