Modified: trunk/Source/_javascript_Core/ChangeLog (115749 => 115750)
--- trunk/Source/_javascript_Core/ChangeLog 2012-05-01 21:26:04 UTC (rev 115749)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-05-01 21:34:53 UTC (rev 115750)
@@ -1,3 +1,23 @@
+2012-05-01 Oliver Hunt <[email protected]>
+
+ Physijs demo crashes due to DFG not updating topCallFrame correctly.
+ https://bugs.webkit.org/show_bug.cgi?id=85311
+
+ Reviewed by Filip Pizlo.
+
+ A few of the dfg operations failed to correctly set the topCallFrame,
+ and so everything goes wrong. This patch corrects the effected operations,
+ and makes debug builds poison topCallFrame before calling a dfg operation.
+
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::putByVal):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::prepareForExternalCall):
+ (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck):
+ (JSC::DFG::SpeculativeJIT::appendCallSetResult):
+
2012-04-30 Gavin Barraclough <[email protected]>
Should be able to use YARR JIT without the JS language JIT
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (115749 => 115750)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-05-01 21:26:04 UTC (rev 115749)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-05-01 21:34:53 UTC (rev 115750)
@@ -148,12 +148,13 @@
template<bool strict>
static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
{
- JSGlobalData* globalData = &exec->globalData();
-
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
+
if (isJSArray(baseValue)) {
JSArray* array = asArray(baseValue);
if (array->canSetIndex(index)) {
- array->setIndex(*globalData, index, value);
+ array->setIndex(globalData, index, value);
return;
}
@@ -215,7 +216,8 @@
#endif
JSGlobalData& globalData = exec->globalData();
-
+ NativeCallFrameTracer tracer(&globalData, exec);
+
Structure* structure;
if (prototype->isObject())
structure = asObject(prototype)->inheritorID(globalData);
@@ -278,6 +280,9 @@
static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
{
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
+
// FIXME: the JIT used to handle these in compiled code!
if (isJSArray(base) && asArray(base)->canGetIndex(index))
return JSValue::encode(asArray(base)->getIndex(index));
@@ -486,6 +491,9 @@
EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
{
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
+
if (!base->inherits(&RegExpObject::s_info))
return throwVMTypeError(exec);
@@ -496,6 +504,9 @@
size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
{
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
+
if (!base->inherits(&RegExpObject::s_info)) {
throwTypeError(exec);
return false;
@@ -987,11 +998,15 @@
EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState* exec, size_t start, size_t size)
{
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
return JSValue::encode(constructArray(exec, exec->codeBlock()->constantBuffer(start), size));
}
EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
{
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
RegExp* regexp = static_cast<RegExp*>(regexpPtr);
if (!regexp->isValid()) {
throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
@@ -1004,6 +1019,7 @@
JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
{
JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
JSActivation* activation = JSActivation::create(
globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
exec->setScopeChain(exec->scopeChain()->push(activation));
@@ -1014,12 +1030,16 @@
{
ASSERT(activation);
ASSERT(activation->inherits(&JSActivation::s_info));
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
jsCast<JSActivation*>(activation)->tearOff(exec->globalData());
}
JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
{
ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
+ JSGlobalData& globalData = exec->globalData();
+ NativeCallFrameTracer tracer(&globalData, exec);
return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain());
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (115749 => 115750)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-05-01 21:26:04 UTC (rev 115749)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2012-05-01 21:34:53 UTC (rev 115750)
@@ -1262,6 +1262,7 @@
#else
JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
{
+ prepareForExternalCall();
m_jit.setupArguments(arg1);
JITCompiler::Call call = m_jit.appendCall(operation);
m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
@@ -1455,10 +1456,21 @@
return appendCallSetResult(operation, result);
}
#endif
+
+#ifndef NDEBUG
+ void prepareForExternalCall()
+ {
+ for (unsigned i = 0; i < sizeof(void*) / 4; i++)
+ m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.globalData()->topCallFrame) + i * 4);
+ }
+#else
+ void prepareForExternalCall() { }
+#endif
// These methods add call instructions, with optional exception checks & setting results.
JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
{
+ prepareForExternalCall();
CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
CallBeginToken token = m_jit.beginCall();
JITCompiler::Call call = m_jit.appendCall(function);
@@ -1473,6 +1485,7 @@
}
JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
{
+ prepareForExternalCall();
JITCompiler::Call call = m_jit.appendCall(function);
m_jit.move(GPRInfo::returnValueGPR, result);
return call;