Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (89860 => 89861)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-27 21:38:09 UTC (rev 89861)
@@ -1,3 +1,33 @@
+2011-06-27 Filip Pizlo <[email protected]>
+
+ Reviewed by Gavin Barraclough.
+
+ DFG JIT does not perform put_by_id caching.
+ https://bugs.webkit.org/show_bug.cgi?id=63409
+
+ * bytecode/StructureStubInfo.h:
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::cachedPutById):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::addPropertyAccess):
+ (JSC::DFG::JITCompiler::PropertyAccessRecord::PropertyAccessRecord):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::dfgRepatchByIdSelfAccess):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::appropriatePutByIdFunction):
+ (JSC::DFG::tryCachePutByID):
+ (JSC::DFG::dfgRepatchPutByID):
+ * dfg/DFGRepatch.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
2011-06-27 Gustavo Noronha Silva <[email protected]>
Unreviewed build fix. One more filed missing during distcheck, for
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (89860 => 89861)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2011-06-27 21:38:09 UTC (rev 89861)
@@ -133,7 +133,7 @@
union {
struct {
intptr_t deltaCheckToCall;
- intptr_t deltaCallToLoad;
+ intptr_t deltaCallToLoadOrStore;
} unset;
struct {
WriteBarrierBase<Structure> baseObjectStructure;
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -350,6 +350,47 @@
m_jit.addPropertyAccess(functionCall, checkToCall, callToLoad);
}
+void JITCodeGenerator::cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
+{
+ JITCompiler::DataLabelPtr structureToCompare;
+ JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::Equal, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+
+ if (slowPathTarget.isSet())
+ slowPathTarget.link(&m_jit);
+
+ silentSpillAllRegisters(InvalidGPRReg, baseGPR, valueGPR);
+ setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(valueGPR, baseGPR);
+ m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR3);
+ m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ V_DFGOperation_EJJI optimizedCall;
+ if (m_jit.codeBlock()->isStrictMode()) {
+ if (putKind == Direct)
+ optimizedCall = operationPutByIdDirectStrictOptimize;
+ else
+ optimizedCall = operationPutByIdStrictOptimize;
+ } else {
+ if (putKind == Direct)
+ optimizedCall = operationPutByIdDirectNonStrictOptimize;
+ else
+ optimizedCall = operationPutByIdNonStrictOptimize;
+ }
+ JITCompiler::Call functionCall = appendCallWithExceptionCheck(optimizedCall);
+ silentFillAllRegisters(InvalidGPRReg);
+
+ JITCompiler::Jump handledByC = m_jit.jump();
+ structureCheck.link(&m_jit);
+
+ m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
+ JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
+
+ intptr_t checkToCall = m_jit.differenceBetween(structureToCompare, functionCall);
+ intptr_t callToStore = m_jit.differenceBetween(functionCall, storeWithPatch);
+
+ handledByC.link(&m_jit);
+
+ m_jit.addPropertyAccess(functionCall, checkToCall, callToStore);
+}
+
#ifndef NDEBUG
static const char* dataFormatString(DataFormat format)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-06-27 21:38:09 UTC (rev 89861)
@@ -501,6 +501,7 @@
}
void cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+ void cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
// Called once a node has completed code generation but prior to setting
// its result, to free up its children. (This must happen prior to setting
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -388,7 +388,7 @@
StructureStubInfo& info = m_codeBlock->structureStubInfo(i);
info.callReturnLocation = linkBuffer.locationOf(m_propertyAccesses[i].m_functionCall);
info.u.unset.deltaCheckToCall = m_propertyAccesses[i].m_deltaCheckToCall;
- info.u.unset.deltaCallToLoad = m_propertyAccesses[i].m_deltaCallToLoad;
+ info.u.unset.deltaCallToLoadOrStore = m_propertyAccesses[i].m_deltaCallToLoadOrStore;
}
// FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs.
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-06-27 21:38:09 UTC (rev 89861)
@@ -232,9 +232,9 @@
void clearSamplingFlag(int32_t flag);
#endif
- void addPropertyAccess(JITCompiler::Call functionCall, intptr_t deltaCheckToCall, intptr_t deltaCallToLoad)
+ void addPropertyAccess(JITCompiler::Call functionCall, intptr_t deltaCheckToCall, intptr_t deltaCallToLoadOrStore)
{
- m_propertyAccesses.append(PropertyAccessRecord(functionCall, deltaCheckToCall, deltaCallToLoad));
+ m_propertyAccesses.append(PropertyAccessRecord(functionCall, deltaCheckToCall, deltaCallToLoadOrStore));
}
private:
@@ -258,16 +258,16 @@
Vector<CallRecord> m_calls;
struct PropertyAccessRecord {
- PropertyAccessRecord(JITCompiler::Call functionCall, intptr_t deltaCheckToCall, intptr_t deltaCallToLoad)
+ PropertyAccessRecord(JITCompiler::Call functionCall, intptr_t deltaCheckToCall, intptr_t deltaCallToLoadOrStore)
: m_functionCall(functionCall)
, m_deltaCheckToCall(deltaCheckToCall)
- , m_deltaCallToLoad(deltaCallToLoad)
+ , m_deltaCallToLoadOrStore(deltaCallToLoadOrStore)
{
}
JITCompiler::Call m_functionCall;
intptr_t m_deltaCheckToCall;
- intptr_t m_deltaCallToLoad;
+ intptr_t m_deltaCallToLoadOrStore;
};
Vector<PropertyAccessRecord, 4> m_propertyAccesses;
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -770,11 +770,14 @@
case PutById: {
JSValueOperand base(this, node.child1);
JSValueOperand value(this, node.child2);
+ GPRTemporary scratch(this, base);
GPRReg valueGPR = value.gpr();
GPRReg baseGPR = base.gpr();
- flushRegisters();
+
+ JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdStrict : operationPutByIdNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), NotDirect, notCell);
+
noResult(m_compileIndex);
break;
}
@@ -782,11 +785,14 @@
case PutByIdDirect: {
JSValueOperand base(this, node.child1);
JSValueOperand value(this, node.child2);
+ GPRTemporary scratch(this, base);
GPRReg valueGPR = value.gpr();
GPRReg baseGPR = base.gpr();
- flushRegisters();
+
+ JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdDirectStrict : operationPutByIdDirectNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), Direct, notCell);
+
noResult(m_compileIndex);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -43,6 +43,7 @@
"jmp _" STRINGIZE(function) "WithReturnAddress" "\n" \
);
#define FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
+#define FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
namespace JSC { namespace DFG {
@@ -284,6 +285,74 @@
JSValue::decode(encodedBase).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot);
}
+void operationPutByIdStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdStrictOptimize);
+void operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
+{
+ JSValue value = JSValue::decode(encodedValue);
+ JSValue base = JSValue::decode(encodedBase);
+ PutPropertySlot slot(true);
+
+ base.put(exec, *propertyName, value, slot);
+
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (stubInfo.seen)
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, NotDirect);
+ else
+ stubInfo.seen = true;
+}
+
+void operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdNonStrictOptimize);
+void operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
+{
+ JSValue value = JSValue::decode(encodedValue);
+ JSValue base = JSValue::decode(encodedBase);
+ PutPropertySlot slot(false);
+
+ base.put(exec, *propertyName, value, slot);
+
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (stubInfo.seen)
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, NotDirect);
+ else
+ stubInfo.seen = true;
+}
+
+void operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectStrictOptimize);
+void operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
+{
+ JSValue value = JSValue::decode(encodedValue);
+ JSValue base = JSValue::decode(encodedBase);
+ PutPropertySlot slot(true);
+
+ base.putDirect(exec, *propertyName, value, slot);
+
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (stubInfo.seen)
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
+ else
+ stubInfo.seen = true;
+}
+
+void operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(operationPutByIdDirectNonStrictOptimize);
+void operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier* propertyName, ReturnAddressPtr returnAddress)
+{
+ JSValue value = JSValue::decode(encodedValue);
+ JSValue base = JSValue::decode(encodedBase);
+ PutPropertySlot slot(false);
+
+ base.putDirect(exec, *propertyName, value, slot);
+
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (stubInfo.seen)
+ dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
+ else
+ stubInfo.seen = true;
+}
+
bool operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
return jsLess(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-06-27 21:38:09 UTC (rev 89861)
@@ -31,6 +31,9 @@
#include <dfg/DFGJITCompiler.h>
namespace JSC { namespace DFG {
+
+enum PutKind { Direct, NotDirect };
+
extern "C" {
// These typedefs provide typechecking when generating calls out to helper routines;
@@ -64,6 +67,10 @@
void operationPutByIdNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
void operationPutByIdDirectStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
void operationPutByIdDirectNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdStrictOptimize(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdNonStrictOptimize(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdDirectStrictOptimize(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
+void operationPutByIdDirectNonStrictOptimize(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*);
bool operationCompareLess(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
bool operationCompareLessEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -28,7 +28,6 @@
#if ENABLE(DFG_JIT)
-#include "DFGOperations.h"
#include "RepatchBuffer.h"
namespace JSC { namespace DFG {
@@ -39,16 +38,19 @@
repatchBuffer.relink(call, newCalleeFunction);
}
-static void dfgRepatchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, size_t offset)
+static void dfgRepatchByIdSelfAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, size_t offset, const FunctionPtr &slowPathFunction, bool compact)
{
RepatchBuffer repatchBuffer(codeBlock);
// Only optimize once!
- repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
+ repatchBuffer.relink(stubInfo.callReturnLocation, slowPathFunction);
// Patch the structure check & the offset of the load.
repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelPtrAtOffset(-(intptr_t)stubInfo.u.unset.deltaCheckToCall), structure);
- repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.u.unset.deltaCallToLoad), sizeof(JSValue) * offset);
+ if (compact)
+ repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.u.unset.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
+ else
+ repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.u.unset.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
}
static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier&, const PropertySlot& slot, StructureStubInfo& stubInfo)
@@ -76,7 +78,7 @@
if ((slot.cachedPropertyType() != PropertySlot::Value) || ((slot.cachedOffset() * sizeof(JSValue)) > (unsigned)MacroAssembler::MaximumCompactPtrAlignedAddressOffset))
return false;
- dfgRepatchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset());
+ dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetById, true);
stubInfo.initGetByIdSelf(*globalData, codeBlock->ownerExecutable(), structure);
return true;
}
@@ -92,6 +94,53 @@
dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);
}
+static V_DFGOperation_EJJI appropriatePutByIdFunction(const PutPropertySlot &slot, PutKind putKind)
+{
+ if (slot.isStrictMode()) {
+ if (putKind == Direct)
+ return operationPutByIdDirectStrict;
+ return operationPutByIdStrict;
+ }
+ if (putKind == Direct)
+ return operationPutByIdDirectNonStrict;
+ return operationPutByIdNonStrict;
+}
+
+static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier&, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+{
+ CodeBlock* codeBlock = exec->codeBlock();
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (!baseValue.isCell())
+ return false;
+ JSCell* baseCell = baseValue.asCell();
+ Structure* structure = baseCell->structure();
+ if (!slot.isCacheable())
+ return false;
+ if (structure->isUncacheableDictionary())
+ return false;
+
+ // Optimize self access.
+ if (slot.base() == baseValue) {
+ if (slot.type() == PutPropertySlot::NewProperty)
+ return false;
+
+ dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), appropriatePutByIdFunction(slot, putKind), false);
+ stubInfo.initPutByIdReplace(*globalData, codeBlock->ownerExecutable(), structure);
+ return true;
+ }
+
+ // FIXME: should support the transition case!
+ return false;
+}
+
+void dfgRepatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+{
+ bool cached = tryCachePutByID(exec, baseValue, propertyName, slot, stubInfo, putKind);
+ if (!cached)
+ dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriatePutByIdFunction(slot, putKind));
+}
+
} } // namespace JSC::DFG
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.h (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.h 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.h 2011-06-27 21:38:09 UTC (rev 89861)
@@ -29,10 +29,12 @@
#if ENABLE(DFG_JIT)
#include <dfg/DFGJITCompiler.h>
+#include <dfg/DFGOperations.h>
namespace JSC { namespace DFG {
void dfgRepatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
+void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
} } // namespace JSC::DFG
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (89860 => 89861)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-27 21:24:55 UTC (rev 89860)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-27 21:38:09 UTC (rev 89861)
@@ -863,25 +863,23 @@
}
case PutById: {
- JSValueOperand base(this, node.child1);
+ SpeculateCellOperand base(this, node.child1);
JSValueOperand value(this, node.child2);
- GPRReg valueGPR = value.gpr();
- GPRReg baseGPR = base.gpr();
- flushRegisters();
+ GPRTemporary scratch(this, base);
- callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdStrict : operationPutByIdNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), NotDirect);
+
noResult(m_compileIndex);
break;
}
case PutByIdDirect: {
- JSValueOperand base(this, node.child1);
+ SpeculateCellOperand base(this, node.child1);
JSValueOperand value(this, node.child2);
- GPRReg valueGPR = value.gpr();
- GPRReg baseGPR = base.gpr();
- flushRegisters();
+ GPRTemporary scratch(this, base);
- callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByIdDirectStrict : operationPutByIdDirectNonStrict, valueGPR, baseGPR, identifier(node.identifierNumber()));
+ cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), Direct);
+
noResult(m_compileIndex);
break;
}