diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-09-20 14:01:09 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-09-20 14:01:09 +0200 |
commit | 6dbcd09121fe266c7704a524b5cbd7f2754659c0 (patch) | |
tree | 5ae0d16cec0cc61f576d51c57b3a4613c7e91e22 /Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | |
parent | 6bbb7fbbac94d0f511a7bd0cbd50854ab643bfb2 (diff) |
Imported WebKit commit 080af0beaa6f0ba8ff8f44cb8bd8b5dcf75ac0af (http://svn.webkit.org/repository/webkit/trunk@129119)
New snapshot with prospective build fix for incorrect QtWebKit master module header file creation
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 07cb11032..0228f846a 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -325,7 +325,7 @@ void SpeculativeJIT::checkArray(Node& node) MacroAssembler::Zero, MacroAssembler::Address(temp.gpr(), Structure::indexingTypeOffset()), MacroAssembler::TrustedImm32( - isSlowPutAccess(node.arrayMode()) ? HasSlowPutArrayStorage : HasArrayStorage))); + isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage))); noResult(m_compileIndex); return; @@ -347,7 +347,7 @@ void SpeculativeJIT::checkArray(Node& node) Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32( MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32( - isSlowPutAccess(node.arrayMode()) ? HasSlowPutArrayStorage : HasArrayStorage))); + isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage))); noResult(m_compileIndex); return; @@ -384,6 +384,80 @@ void SpeculativeJIT::checkArray(Node& node) noResult(m_compileIndex); } +void SpeculativeJIT::arrayify(Node& node) +{ + ASSERT(modeIsSpecific(node.arrayMode())); + ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode())); + + SpeculateCellOperand base(this, node.child1()); + GPRReg baseReg = base.gpr(); + + switch (node.arrayMode()) { + case EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES: { + GPRTemporary structure(this); + GPRTemporary temp(this); + GPRReg structureGPR = structure.gpr(); + GPRReg tempGPR = temp.gpr(); + + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); + + // We can skip all that comes next if we already have array storage. + IndexingType desiredIndexingTypeMask = + isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage; + MacroAssembler::Jump slowCase = m_jit.branchTest8( + MacroAssembler::Zero, + MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), + MacroAssembler::TrustedImm32(desiredIndexingTypeMask)); + + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), tempGPR); + + MacroAssembler::Jump done = m_jit.jump(); + + slowCase.link(&m_jit); + + // Next check that the object does not intercept indexed accesses. If it does, + // then this mode won't work. + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branchTest8( + MacroAssembler::NonZero, + MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()), + MacroAssembler::TrustedImm32(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero))); + + // Now call out to create the array storage. + silentSpillAllRegisters(tempGPR); + callOperation(operationEnsureArrayStorage, tempGPR, baseReg); + silentFillAllRegisters(tempGPR); + + // Alas, we need to reload the structure because silent spilling does not save + // temporaries. Nor would it be useful for it to do so. Either way we're talking + // about a load. + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); + + // Finally, check that we have the kind of array storage that we wanted to get. + // Note that this is a backwards speculation check, which will result in the + // bytecode operation corresponding to this arrayification being reexecuted. + // That's fine, since arrayification is not user-visible. + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branchTest8( + MacroAssembler::Zero, + MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), + MacroAssembler::TrustedImm32(desiredIndexingTypeMask))); + + done.link(&m_jit); + storageResult(tempGPR, m_compileIndex); + break; + } + default: + ASSERT_NOT_REACHED(); + break; + } +} + GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex) { Node& node = m_jit.graph()[nodeIndex]; |