https://bugs.webkit.org/show_bug.cgi?id=73722
Reviewed by Gavin Barraclough.
Add basic support for float typed arrays in JSC. This is currently
less optimal than it could be in the following ways:
* float32Array1[0] = float32Array2[0] (eg. an element by element copy)
promotes float to double and then back to float.
* float64Array[0] will always perform NaN tests in order to prevent
signalling NaNs from entering the engine.
We also don't support Float32Array on ARMv7
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::loadDouble):
(JSC::MacroAssemblerARMv7::loadFloat):
(JSC::MacroAssemblerARMv7::storeDouble):
(JSC::MacroAssemblerARMv7::storeFloat):
(JSC::MacroAssemblerARMv7::convertFloatToDouble):
(JSC::MacroAssemblerARMv7::convertDoubleToFloat):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::loadDouble):
(JSC::MacroAssemblerX86Common::loadFloat):
(JSC::MacroAssemblerX86Common::storeDouble):
(JSC::MacroAssemblerX86Common::storeFloat):
(JSC::MacroAssemblerX86Common::convertDoubleToFloat):
(JSC::MacroAssemblerX86Common::convertFloatToDouble):
* assembler/X86Assembler.h:
(JSC::X86Assembler::cvtsd2ss_rr):
(JSC::X86Assembler::cvtss2sd_rr):
(JSC::X86Assembler::movsd_rm):
(JSC::X86Assembler::movss_rm):
(JSC::X86Assembler::movsd_mr):
(JSC::X86Assembler::movss_mr):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateFloat32Array):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::compile):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@101886
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-12-02 Oliver Hunt <oliver@apple.com>
+
+ Improve float array support in the DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=73722
+
+ Reviewed by Gavin Barraclough.
+
+ Add basic support for float typed arrays in JSC. This is currently
+ less optimal than it could be in the following ways:
+ * float32Array1[0] = float32Array2[0] (eg. an element by element copy)
+ promotes float to double and then back to float.
+ * float64Array[0] will always perform NaN tests in order to prevent
+ signalling NaNs from entering the engine.
+
+ We also don't support Float32Array on ARMv7
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::loadDouble):
+ (JSC::MacroAssemblerARMv7::loadFloat):
+ (JSC::MacroAssemblerARMv7::storeDouble):
+ (JSC::MacroAssemblerARMv7::storeFloat):
+ (JSC::MacroAssemblerARMv7::convertFloatToDouble):
+ (JSC::MacroAssemblerARMv7::convertDoubleToFloat):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::loadDouble):
+ (JSC::MacroAssemblerX86Common::loadFloat):
+ (JSC::MacroAssemblerX86Common::storeDouble):
+ (JSC::MacroAssemblerX86Common::storeFloat):
+ (JSC::MacroAssemblerX86Common::convertDoubleToFloat):
+ (JSC::MacroAssemblerX86Common::convertFloatToDouble):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::cvtsd2ss_rr):
+ (JSC::X86Assembler::cvtss2sd_rr):
+ (JSC::X86Assembler::movsd_rm):
+ (JSC::X86Assembler::movss_rm):
+ (JSC::X86Assembler::movsd_mr):
+ (JSC::X86Assembler::movss_mr):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldSpeculateFloat32Array):
+ * dfg/DFGPropagator.cpp:
+ (JSC::DFG::Propagator::propagateNodePredictions):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::compile):
+
2011-12-02 Sheriff Bot <webkit.review.bot@gmail.com>
Unreviewed, rolling out r101801.
m_assembler.vldr(dest, base, offset);
}
+ void loadDouble(BaseIndex address, FPRegisterID dest)
+ {
+ ASSERT_NOT_REACHED();
+ }
+
+ void loadFloat(BaseIndex address, FPRegisterID dest)
+ {
+ ASSERT_NOT_REACHED();
+ }
+
void moveDouble(FPRegisterID src, FPRegisterID dest)
{
if (src != dest)
storeDouble(src, addressTempRegister);
}
+ void storeDouble(FPRegisterID src, BaseIndex address)
+ {
+ move(address.index, addressTempRegister);
+ mul32(TrustedImm32(address.scale), addressTempRegister, addressTempRegister);
+ storeDouble(src, Address(addressTempRegister, address.offset));
+ }
+
+ void storeFloat(FPRegisterID src, BaseIndex address)
+ {
+ move(address.index, addressTempRegister);
+ mul32(TrustedImm32(address.scale), addressTempRegister, addressTempRegister);
+ storeDouble(ARMRegisters::asSingle(src), Address(addressTempRegister, address.offset));
+ }
+
void addDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.vadd(dest, dest, src);
m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle());
}
+
+ void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT_NOT_REACHED();
+ }
+
+ void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT_NOT_REACHED();
+ }
Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
{
ASSERT(isSSE2Present());
m_assembler.movsd_mr(address.offset, address.base, dest);
}
+
+ void loadDouble(BaseIndex address, FPRegisterID dest)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.movsd_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+ void loadFloat(BaseIndex address, FPRegisterID dest)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.movss_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
ASSERT(isSSE2Present());
m_assembler.movsd_rm(src, address.offset, address.base);
}
+
+ void storeDouble(FPRegisterID src, BaseIndex address)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.movsd_rm(src, address.offset, address.base, address.index, address.scale);
+ }
+
+ void storeFloat(FPRegisterID src, BaseIndex address)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.movss_rm(src, address.offset, address.base, address.index, address.scale);
+ }
+
+ void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.cvtsd2ss_rr(src, dst);
+ }
+
+ void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.cvtss2sd_rr(src, dst);
+ }
void addDouble(FPRegisterID src, FPRegisterID dest)
{
OP_CALL_rel32 = 0xE8,
OP_JMP_rel32 = 0xE9,
PRE_SSE_F2 = 0xF2,
+ PRE_SSE_F3 = 0xF3,
OP_HLT = 0xF4,
OP_GROUP3_EbIb = 0xF6,
OP_GROUP3_Ev = 0xF7,
typedef enum {
OP2_MOVSD_VsdWsd = 0x10,
OP2_MOVSD_WsdVsd = 0x11,
+ OP2_MOVSS_VsdWsd = 0x10,
+ OP2_MOVSS_WsdVsd = 0x11,
OP2_CVTSI2SD_VsdEd = 0x2A,
OP2_CVTTSD2SI_GdWsd = 0x2C,
OP2_UCOMISD_VsdWsd = 0x2E,
OP2_ADDSD_VsdWsd = 0x58,
OP2_MULSD_VsdWsd = 0x59,
+ OP2_CVTSD2SS_VsdWsd = 0x5A,
+ OP2_CVTSS2SD_VsdWsd = 0x5A,
OP2_SUBSD_VsdWsd = 0x5C,
OP2_DIVSD_VsdWsd = 0x5E,
OP2_SQRTSD_VsdWsd = 0x51,
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
}
+
+ void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src);
+ }
+
+ void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F3);
+ m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src);
+ }
#if CPU(X86_64)
void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst)
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
}
-
+
+ void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
+ }
+
+ void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.prefix(PRE_SSE_F3);
+ m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
+ }
+
void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
}
+ void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
+ }
+
+ void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F3);
+ m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
+ }
+
#if !CPU(X86_64)
void movsd_mr(const void* address, XMMRegisterID dst)
{
forNode(nodeIndex).set(PredictDouble);
break;
}
+ if (m_graph[node.child1()].shouldSpeculateFloat32Array()) {
+ forNode(node.child1()).filter(PredictFloat32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictDouble);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateFloat64Array()) {
+ forNode(node.child1()).filter(PredictFloat64Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictDouble);
+ break;
+ }
forNode(node.child1()).filter(PredictArray);
forNode(node.child2()).filter(PredictInt32);
forNode(nodeIndex).makeTop();
forNode(node.child3()).filter(PredictNumber);
break;
}
+ if (m_graph[node.child1()].shouldSpeculateFloat32Array()) {
+ forNode(node.child1()).filter(PredictFloat32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateFloat64Array()) {
+ forNode(node.child1()).filter(PredictFloat64Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
forNode(node.child1()).filter(PredictArray);
forNode(node.child2()).filter(PredictInt32);
bool shouldSpeculateFloat32Array()
{
- return prediction() == PredictFloat32Array;
+#if CPU(X86) || CPU(X86_64)
+ return !!(prediction() & PredictFloat32Array);
+#else
+ return false;
+#endif
}
bool shouldSpeculateFloat64Array()
}
case GetByVal: {
- if (m_graph[node.child1()].shouldSpeculateUint32Array())
+ if (m_graph[node.child1()].shouldSpeculateUint32Array() || m_graph[node.child1()].shouldSpeculateFloat32Array() || m_graph[node.child1()].shouldSpeculateFloat64Array())
changed |= mergePrediction(PredictDouble);
else if (node.getHeapPrediction())
changed |= mergePrediction(node.getHeapPrediction());
GPRTemporary result(this);
FPRReg fpr = valueOp.fpr();
GPRReg gpr = result.gpr();
+ MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
+ m_jit.xorPtr(gpr, gpr);
+ MacroAssembler::Jump fixed = m_jit.jump();
+ notNaN.link(&m_jit);
+
if (signedness == SignedTypedArray)
m_jit.truncateDoubleToInt32(fpr, gpr);
else
m_jit.truncateDoubleToUint32(fpr, gpr);
+ fixed.link(&m_jit);
value.adopt(result);
valueGPR = gpr;
}
noResult(m_compileIndex);
}
+void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
+{
+ ASSERT(node.child3() == NoNode);
+ SpeculateCellOperand base(this, node.child1());
+ SpeculateStrictInt32Operand property(this, node.child2());
+ GPRReg baseReg = base.gpr();
+ GPRReg propertyReg = property.gpr();
+
+ if (speculationRequirements != NoTypedArrayTypeSpecCheck)
+ speculationCheck(JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+
+ // Load the character into scratchReg
+ GPRTemporary storage(this);
+ GPRReg storageReg = storage.gpr();
+ m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
+ FPRTemporary result(this);
+ FPRReg resultReg = result.fpr();
+ ASSERT(speculationRequirements != NoTypedArraySpecCheck);
+ MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
+ m_jit.breakpoint();
+ MacroAssembler::Jump outOfBounds = m_jit.jump();
+ inBounds.link(&m_jit);
+ switch (elementSize) {
+ case 4:
+ m_jit.loadFloat(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
+ m_jit.convertFloatToDouble(resultReg, resultReg);
+ break;
+ case 8: {
+ m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
+ MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
+ static const double NaN = std::numeric_limits<double>::quiet_NaN();
+ m_jit.loadDouble(&NaN, resultReg);
+ notNaN.link(&m_jit);
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ outOfBounds.link(&m_jit);
+ doubleResult(resultReg, m_compileIndex);
+}
+
+void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
+{
+ NodeIndex baseIndex = node.child1();
+ NodeIndex valueIndex = node.child3();
+
+ SpeculateDoubleOperand valueOp(this, valueIndex);
+
+ if (speculationRequirements != NoTypedArrayTypeSpecCheck)
+ speculationCheck(JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
+
+ GPRTemporary result(this);
+
+ GPRTemporary storage(this);
+ GPRReg storageReg = storage.gpr();
+
+ m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
+ MacroAssembler::Jump outOfBounds;
+ if (speculationRequirements != NoTypedArraySpecCheck)
+ outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
+
+ switch (elementSize) {
+ case 4: {
+ FPRTemporary scratch(this);
+ m_jit.moveDouble(valueOp.fpr(), scratch.fpr());
+ m_jit.convertDoubleToFloat(valueOp.fpr(), scratch.fpr());
+ m_jit.storeFloat(scratch.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
+ break;
+ }
+ case 8:
+ m_jit.storeDouble(valueOp.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ if (speculationRequirements != NoTypedArraySpecCheck)
+ outOfBounds.link(&m_jit);
+ noResult(m_compileIndex);
+}
+
void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
{
// Check that prototype is an object.
};
void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements, TypedArraySignedness);
void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements, TypedArraySignedness);
+ void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements);
+ void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements);
// It is acceptable to have structure be equal to scratch, so long as you're fine
// with the structure GPR being clobbered.
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float), isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double), isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
ASSERT(node.child3() == NoNode);
SpeculateCellOperand base(this, node.child1());
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
JSValueOperand value(this, node.child3());
GPRTemporary scratch(this);
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
JSValueOperand value(this, node.child3());
GPRTemporary scratch(this, base);
}
case DataFormatDouble:
+ case DataFormatJSDouble: {
+ if (node.hasConstant() && isInt32Constant(nodeIndex)) {
+ GPRReg gpr = allocate();
+ ASSERT(isInt32Constant(nodeIndex));
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ returnFormat = DataFormatInteger;
+ return gpr;
+ }
+ }
case DataFormatCell:
case DataFormatBoolean:
- case DataFormatJSDouble:
case DataFormatJSCell:
case DataFormatJSBoolean: {
terminateSpeculativeExecution(JSValueRegs(), NoNode);
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float), isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double), isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
ASSERT(node.child3() == NoNode);
SpeculateCellOperand base(this, node.child1());
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
JSValueOperand value(this, node.child3());
GPRTemporary scratch(this);
return;
break;
}
+
+ if (at(node.child1()).shouldSpeculateFloat32Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
+ if (at(node.child1()).shouldSpeculateFloat64Array()) {
+ compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
JSValueOperand value(this, node.child3());
GPRTemporary scratch(this);