Hi,
Attached is a patch against 10.0.12esr which (hopefully) fixes a bunch
of unaligned memory accesses described in my previous update. It's not
pretty, but a browser compiled with this patch is good enough to
browse www.cnn.com and gmail.com without crashing, and compiler should
be smart enough to optimize away all its effects on arches other than
sparc.
You probably want to run it past some upstream maintainer before
applying, but it is definitely an improvement compared to current
testing version. I'll make the binaries available and ask people on
debian-sparc to test.
Best regards,
--
Jurij Smakov [email protected]
Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC
diff -aur a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp
--- a/js/src/methodjit/Compiler.cpp 2013-01-03 17:43:19.000000000 +0000
+++ b/js/src/methodjit/Compiler.cpp 2013-02-10 20:49:38.925659583 +0000
@@ -965,22 +965,31 @@
}
/* Please keep in sync with JITScript::scriptDataSize! */
- size_t dataSize = sizeof(JITScript) +
- sizeof(NativeMapEntry) * nNmapLive +
- sizeof(InlineFrame) * inlineFrames.length() +
- sizeof(CallSite) * callSites.length() +
+ size_t dataSize = sizeof(JITScript);
+ dataSize += ALIGN_TO(dataSize, NativeMapEntry) +
+ sizeof(NativeMapEntry) * nNmapLive;
+ dataSize += ALIGN_TO(dataSize, InlineFrame) +
+ sizeof(InlineFrame) * inlineFrames.length();
+ dataSize += ALIGN_TO(dataSize, CallSite) +
+ sizeof(CallSite) * callSites.length();
#if defined JS_MONOIC
- sizeof(ic::GetGlobalNameIC) * getGlobalNames.length() +
- sizeof(ic::SetGlobalNameIC) * setGlobalNames.length() +
- sizeof(ic::CallICInfo) * callICs.length() +
- sizeof(ic::EqualityICInfo) * equalityICs.length() +
+ dataSize += ALIGN_TO(dataSize, ic::GetGlobalNameIC) +
+ sizeof(ic::GetGlobalNameIC) * getGlobalNames.length();
+ dataSize += ALIGN_TO(dataSize, ic::SetGlobalNameIC) +
+ sizeof(ic::SetGlobalNameIC) * setGlobalNames.length();
+ dataSize += ALIGN_TO(dataSize, ic::CallICInfo) +
+ sizeof(ic::CallICInfo) * callICs.length();
+ dataSize += ALIGN_TO(dataSize, ic::EqualityICInfo) +
+ sizeof(ic::EqualityICInfo) * equalityICs.length();
#endif
#if defined JS_POLYIC
- sizeof(ic::PICInfo) * pics.length() +
- sizeof(ic::GetElementIC) * getElemICs.length() +
- sizeof(ic::SetElementIC) * setElemICs.length() +
+ dataSize += ALIGN_TO(dataSize, ic::GetElementIC) +
+ sizeof(ic::GetElementIC) * getElemICs.length();
+ dataSize += ALIGN_TO(dataSize, ic::SetElementIC) +
+ sizeof(ic::SetElementIC) * setElemICs.length();
+ dataSize += ALIGN_TO(dataSize, ic::PICInfo) +
+ sizeof(ic::PICInfo) * pics.length();
#endif
- 0;
uint8 *cursor = (uint8 *)cx->calloc_(dataSize);
if (!cursor) {
@@ -1014,6 +1023,7 @@
Label *jumpMap = a->jumpMap;
/* Build the pc -> ncode mapping. */
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, NativeMapEntry);
NativeMapEntry *jitNmap = (NativeMapEntry *)cursor;
jit->nNmapPairs = nNmapLive;
cursor += sizeof(NativeMapEntry) * jit->nNmapPairs;
@@ -1049,6 +1059,7 @@
JS_ASSERT(ix == jit->nNmapPairs);
/* Build the table of inlined frames. */
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, InlineFrame);
InlineFrame *jitInlineFrames = (InlineFrame *)cursor;
jit->nInlineFrames = inlineFrames.length();
cursor += sizeof(InlineFrame) * jit->nInlineFrames;
@@ -1065,6 +1076,7 @@
}
/* Build the table of call sites. */
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, CallSite);
CallSite *jitCallSites = (CallSite *)cursor;
jit->nCallSites = callSites.length();
cursor += sizeof(CallSite) * jit->nCallSites;
@@ -1109,6 +1121,7 @@
jit->argsCheckPool = NULL;
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::GetGlobalNameIC);
ic::GetGlobalNameIC *getGlobalNames_ = (ic::GetGlobalNameIC *)cursor;
jit->nGetGlobalNames = getGlobalNames.length();
cursor += sizeof(ic::GetGlobalNameIC) * jit->nGetGlobalNames;
@@ -1124,6 +1137,7 @@
stubCode.patch(from.addrLabel, &to);
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::SetGlobalNameIC);
ic::SetGlobalNameIC *setGlobalNames_ = (ic::SetGlobalNameIC *)cursor;
jit->nSetGlobalNames = setGlobalNames.length();
cursor += sizeof(ic::SetGlobalNameIC) * jit->nSetGlobalNames;
@@ -1157,6 +1171,7 @@
stubCode.patch(from.addrLabel, &to);
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::CallICInfo);
ic::CallICInfo *jitCallICs = (ic::CallICInfo *)cursor;
jit->nCallICs = callICs.length();
cursor += sizeof(ic::CallICInfo) * jit->nCallICs;
@@ -1217,6 +1232,7 @@
stubCode.patch(callICs[i].addrLabel2, &jitCallICs[i]);
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::EqualityICInfo);
ic::EqualityICInfo *jitEqualityICs = (ic::EqualityICInfo *)cursor;
jit->nEqualityICs = equalityICs.length();
cursor += sizeof(ic::EqualityICInfo) * jit->nEqualityICs;
@@ -1257,6 +1273,7 @@
}
#ifdef JS_POLYIC
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::GetElementIC);
ic::GetElementIC *jitGetElems = (ic::GetElementIC *)cursor;
jit->nGetElems = getElemICs.length();
cursor += sizeof(ic::GetElementIC) * jit->nGetElems;
@@ -1285,6 +1302,7 @@
stubCode.patch(from.paramAddr, &to);
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::SetElementIC);
ic::SetElementIC *jitSetElems = (ic::SetElementIC *)cursor;
jit->nSetElems = setElemICs.length();
cursor += sizeof(ic::SetElementIC) * jit->nSetElems;
@@ -1325,6 +1343,7 @@
stubCode.patch(from.paramAddr, &to);
}
+ cursor += ALIGN_TO(cursor - (uint8 *) jit, ic::PICInfo);
ic::PICInfo *jitPics = (ic::PICInfo *)cursor;
jit->nPICs = pics.length();
cursor += sizeof(ic::PICInfo) * jit->nPICs;
diff -aur a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp
--- a/js/src/methodjit/MethodJIT.cpp 2013-02-09 17:06:16.000000000 +0000
+++ b/js/src/methodjit/MethodJIT.cpp 2013-02-10 20:45:03.017653001 +0000
@@ -1155,19 +1155,22 @@
NativeMapEntry *
JITScript::nmap() const
{
- return (NativeMapEntry *)((char*)this + sizeof(JITScript));
+ char *unalignedPtr = (char *)this + sizeof(JITScript);
+ return (NativeMapEntry *)(unalignedPtr + ALIGN_TO(sizeof(JITScript), NativeMapEntry));
}
js::mjit::InlineFrame *
JITScript::inlineFrames() const
{
- return (js::mjit::InlineFrame *)((char *)nmap() + sizeof(NativeMapEntry) * nNmapPairs);
+ char *unalignedPtr = (char *)nmap() + sizeof(NativeMapEntry) * nNmapPairs;
+ return (js::mjit::InlineFrame *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, js::mjit::InlineFrame));
}
js::mjit::CallSite *
JITScript::callSites() const
{
- return (js::mjit::CallSite *)&inlineFrames()[nInlineFrames];
+ char *unalignedPtr = (char *)&inlineFrames()[nInlineFrames];
+ return (js::mjit::CallSite *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, js::mjit::CallSite));
}
char *
@@ -1180,26 +1183,29 @@
ic::GetGlobalNameIC *
JITScript::getGlobalNames() const
{
- return (ic::GetGlobalNameIC *) commonSectionLimit();
+ char *unalignedPtr = commonSectionLimit();
+ return (ic::GetGlobalNameIC *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::GetGlobalNameIC));
}
ic::SetGlobalNameIC *
JITScript::setGlobalNames() const
{
- return (ic::SetGlobalNameIC *)((char *)getGlobalNames() +
- sizeof(ic::GetGlobalNameIC) * nGetGlobalNames);
+ char *unalignedPtr = (char *)getGlobalNames() + sizeof(ic::GetGlobalNameIC) * nGetGlobalNames;
+ return (ic::SetGlobalNameIC *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::SetGlobalNameIC));
}
ic::CallICInfo *
JITScript::callICs() const
{
- return (ic::CallICInfo *)&setGlobalNames()[nSetGlobalNames];
+ char *unalignedPtr = (char *)&setGlobalNames()[nSetGlobalNames];
+ return (ic::CallICInfo *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::CallICInfo));
}
ic::EqualityICInfo *
JITScript::equalityICs() const
{
- return (ic::EqualityICInfo *)&callICs()[nCallICs];
+ char *unalignedPtr = (char *)&callICs()[nCallICs];
+ return (ic::EqualityICInfo *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::EqualityICInfo));
}
char *
@@ -1219,19 +1225,22 @@
ic::GetElementIC *
JITScript::getElems() const
{
- return (ic::GetElementIC *)monoICSectionsLimit();
+ char *unalignedPtr = monoICSectionsLimit();
+ return (ic::GetElementIC *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::GetElementIC));
}
ic::SetElementIC *
JITScript::setElems() const
{
- return (ic::SetElementIC *)((char *)getElems() + sizeof(ic::GetElementIC) * nGetElems);
+ char *unalignedPtr = (char *)getElems() + sizeof(ic::GetElementIC) * nGetElems;
+ return (ic::SetElementIC *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::SetElementIC));
}
ic::PICInfo *
JITScript::pics() const
{
- return (ic::PICInfo *)((char *)setElems() + sizeof(ic::SetElementIC) * nSetElems);
+ char *unalignedPtr = (char *)setElems() + sizeof(ic::SetElementIC) * nSetElems;
+ return (ic::PICInfo *)(unalignedPtr + ALIGN_TO(unalignedPtr - (char *)this, ic::PICInfo));
}
char *
@@ -1327,23 +1336,34 @@
mjit::JITScript::scriptDataSize(JSUsableSizeFun usf)
{
size_t usable = usf ? usf(this) : 0;
- return usable ? usable :
- sizeof(JITScript) +
- sizeof(NativeMapEntry) * nNmapPairs +
- sizeof(InlineFrame) * nInlineFrames +
- sizeof(CallSite) * nCallSites +
+ if (usable) return usable;
+
+ size_t dataSize = sizeof(JITScript);
+ dataSize += ALIGN_TO(dataSize, NativeMapEntry) +
+ sizeof(NativeMapEntry) * nNmapPairs;
+ dataSize += ALIGN_TO(dataSize, InlineFrame) +
+ sizeof(InlineFrame) * nInlineFrames;
+ dataSize += ALIGN_TO(dataSize, CallSite) +
+ sizeof(CallSite) * nCallSites;
#if defined JS_MONOIC
- sizeof(ic::GetGlobalNameIC) * nGetGlobalNames +
- sizeof(ic::SetGlobalNameIC) * nSetGlobalNames +
- sizeof(ic::CallICInfo) * nCallICs +
- sizeof(ic::EqualityICInfo) * nEqualityICs +
+ dataSize += ALIGN_TO(dataSize, ic::GetGlobalNameIC) +
+ sizeof(ic::GetGlobalNameIC) * nGetGlobalNames;
+ dataSize += ALIGN_TO(dataSize, ic::SetGlobalNameIC) +
+ sizeof(ic::SetGlobalNameIC) * nSetGlobalNames;
+ dataSize += ALIGN_TO(dataSize, ic::CallICInfo) +
+ sizeof(ic::CallICInfo) * nCallICs;
+ dataSize += ALIGN_TO(dataSize, ic::EqualityICInfo) +
+ sizeof(ic::EqualityICInfo) * nEqualityICs;
#endif
#if defined JS_POLYIC
- sizeof(ic::PICInfo) * nPICs +
- sizeof(ic::GetElementIC) * nGetElems +
- sizeof(ic::SetElementIC) * nSetElems +
+ dataSize += ALIGN_TO(dataSize, ic::GetElementIC) +
+ sizeof(ic::GetElementIC) * nGetElems;
+ dataSize += ALIGN_TO(dataSize, ic::SetElementIC) +
+ sizeof(ic::SetElementIC) * nSetElems;
+ dataSize += ALIGN_TO(dataSize, ic::PICInfo) +
+ sizeof(ic::PICInfo) * nPICs;
#endif
- 0;
+ return dataSize;
}
void
diff -aur a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h
--- a/js/src/methodjit/MethodJIT.h 2013-01-03 17:43:19.000000000 +0000
+++ b/js/src/methodjit/MethodJIT.h 2013-02-10 17:43:43.137662496 +0000
@@ -835,5 +835,11 @@
extern "C" void JaegerInterpolinePatched();
#endif
+#ifdef JS_CPU_SPARC
+#define ALIGN_TO(size, type) ((size) % __alignof__(type) ? __alignof__(type) - ((size) % __alignof__(type)) : 0)
+#else
+#define ALIGN_TO(size, type) (0)
+#endif
+
#endif /* jsjaeger_h__ */