Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Unified Diff: src/ia32/lithium-ia32.cc

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index aa91a83406f3479590ab22e87747e8fd7f917b0e..27fa285cfea212d6d8910bf5ae75b78cca14cc5f 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -804,9 +804,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
LInstruction* LChunkBuilder::DoBit(Token::Value op,
HBitwiseBinaryOperation* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (instr->representation().IsInteger()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
@@ -836,9 +836,9 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return MarkAsCall(DefineFixed(result, eax), instr);
}
- ASSERT(instr->representation().IsInteger32());
- ASSERT(instr->OperandAt(0)->representation().IsInteger32());
- ASSERT(instr->OperandAt(1)->representation().IsInteger32());
+ ASSERT(instr->representation().IsInteger());
+ ASSERT(instr->OperandAt(0)->representation().IsInteger32X());
+ ASSERT(instr->OperandAt(1)->representation().IsInteger32X());
LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
HValue* right_value = instr->OperandAt(1);
@@ -854,17 +854,9 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
// Shift operations can only deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32.
- bool can_deopt = (op == Token::SHR && constant_value == 0);
- if (can_deopt) {
- bool can_truncate = true;
- for (int i = 0; i < instr->uses()->length(); i++) {
- if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) {
- can_truncate = false;
- break;
- }
- }
- can_deopt = !can_truncate;
- }
+ bool can_deopt = op == Token::SHR &&
+ constant_value == 0 &&
+ !instr->representation().Equals(Representation::TruncatedInteger32());
LShiftI* result = new LShiftI(op, left, right, can_deopt);
return can_deopt
@@ -1053,9 +1045,9 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
HValue* left = compare->left();
HValue* right = compare->right();
Representation r = compare->GetInputRepresentation();
- if (r.IsInteger32()) {
- ASSERT(left->representation().IsInteger32());
- ASSERT(right->representation().IsInteger32());
+ if (r.IsInteger()) {
+ ASSERT(left->representation().IsInteger());
+ ASSERT(right->representation().IsInteger());
return new LCmpIDAndBranch(UseRegisterAtStart(left),
UseOrConstantAtStart(right));
@@ -1349,8 +1341,8 @@ LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
- ASSERT(instr->value()->representation().IsInteger32());
- ASSERT(instr->representation().IsInteger32());
+ ASSERT(instr->value()->representation().IsInteger());
+ ASSERT(instr->representation().IsInteger32X());
LOperand* input = UseRegisterAtStart(instr->value());
LBitNotI* result = new LBitNotI(input);
return DefineSameAsFirst(result);
@@ -1370,7 +1362,8 @@ LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::DIV, instr);
- } else if (instr->representation().IsInteger32()) {
+ } else if (instr->representation().IsInteger()) {
+ ASSERT(instr->representation().IsInteger32X());
// The temporary operand is necessary to ensure that right is not allocated
// into edx.
LOperand* temp = FixedTemp(edx);
@@ -1386,9 +1379,9 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
LInstruction* LChunkBuilder::DoMod(HMod* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (instr->representation().IsInteger32X()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LInstruction* result;
if (instr->HasPowerOf2Divisor()) {
@@ -1426,9 +1419,9 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
LInstruction* LChunkBuilder::DoMul(HMul* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (instr->representation().IsInteger32X()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
LOperand* right = UseOrConstant(instr->MostConstantOperand());
LOperand* temp = NULL;
@@ -1447,9 +1440,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
LInstruction* LChunkBuilder::DoSub(HSub* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (instr->representation().IsInteger32X()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
LSubI* sub = new LSubI(left, right);
@@ -1468,9 +1461,9 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
- if (instr->representation().IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (instr->representation().IsInteger32X()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
LAddI* add = new LAddI(left, right);
@@ -1507,9 +1500,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
Token::Value op = instr->token();
Representation r = instr->GetInputRepresentation();
- if (r.IsInteger32()) {
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ if (r.IsInteger32X()) {
+ ASSERT(instr->left()->representation().IsInteger());
+ ASSERT(instr->right()->representation().IsInteger());
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
return DefineAsRegister(new LCmpID(left, right));
@@ -1652,18 +1645,21 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LNumberUntagD* res = new LNumberUntagD(value);
return AssignEnvironment(DefineAsRegister(res));
} else {
- ASSERT(to.IsInteger32());
+ ASSERT(to.IsInteger());
LOperand* value = UseRegister(instr->value());
bool needs_check = !instr->value()->type().IsSmi();
+ bool needs_temp = to.IsClampedRoundedInteger8() ||
+ (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
+ ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
if (needs_check) {
- LOperand* xmm_temp =
- (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3))
- ? NULL
- : FixedTemp(xmm1);
- LTaggedToI* res = new LTaggedToI(value, xmm_temp);
+ LOperand* xmm_temp = needs_temp ? FixedTemp(xmm1) : NULL;
+ LTaggedToI* res = new LTaggedToI(value, xmm_temp, rounding_mode);
return AssignEnvironment(DefineSameAsFirst(res));
} else {
- return DefineSameAsFirst(new LSmiUntag(value, needs_check));
+ bool should_clamp = to.IsClampedRoundedInteger8();
+ return DefineSameAsFirst(new LSmiUntag(value,
+ false,
+ should_clamp));
}
}
} else if (from.IsDouble()) {
@@ -1676,15 +1672,18 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LNumberTagD* result = new LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
} else {
- ASSERT(to.IsInteger32());
- bool needs_temp = instr->CanTruncateToInt32() &&
- !CpuFeatures::IsSupported(SSE3);
+ ASSERT(to.IsInteger());
+ ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
+ bool needs_temp = to.IsClampedRoundedInteger8() ||
+ (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
LOperand* value = needs_temp ?
UseTempRegister(instr->value()) : UseRegister(instr->value());
LOperand* temp = needs_temp ? TempRegister() : NULL;
- return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
+ return AssignEnvironment(DefineAsRegister(new LDoubleToI(value,
+ temp,
+ rounding_mode)));
}
- } else if (from.IsInteger32()) {
+ } else if (from.IsInteger()) {
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
@@ -1694,6 +1693,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LNumberTagI* result = new LNumberTagI(value);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
}
+ } else if (to.IsClampedRoundedInteger8()) {
+ return DefineFixed(new LInteger32ToClamped(
+ UseFixed(instr->value(), eax)), eax);
} else {
ASSERT(to.IsDouble());
return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
@@ -1751,7 +1753,7 @@ LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
Representation r = instr->representation();
- if (r.IsInteger32()) {
+ if (r.IsInteger()) {
return DefineAsRegister(new LConstantI);
} else if (r.IsDouble()) {
double value = instr->DoubleValue();
@@ -1878,7 +1880,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32X());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
@@ -1890,9 +1892,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) {
ExternalArrayType array_type = instr->array_type();
Representation representation(instr->representation());
- ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+ ASSERT((representation.IsInteger32X() && array_type != kExternalFloatArray) ||
(representation.IsDouble() && array_type == kExternalFloatArray));
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32X());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegister(instr->key());
LLoadKeyedSpecializedArrayElement* result =
@@ -1922,7 +1924,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32X());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
@@ -1940,25 +1942,16 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation());
ExternalArrayType array_type = instr->array_type();
- ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
- (representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->external_pointer()->representation().IsExternal());
- ASSERT(instr->key()->representation().IsInteger32());
+ ASSERT(instr->key()->representation().IsInteger32X());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegister(instr->key());
- LOperand* temp = NULL;
-
- if (array_type == kExternalPixelArray) {
- // The generated code for pixel array stores requires that the clamped value
- // is in a byte register. eax is an arbitrary choice to satisfy this
- // requirement.
- temp = FixedTemp(eax);
- }
LOperand* val = NULL;
if (array_type == kExternalByteArray ||
- array_type == kExternalUnsignedByteArray) {
+ array_type == kExternalUnsignedByteArray ||
+ array_type == kExternalPixelArray) {
// We need a byte register in this case for the value.
val = UseFixed(instr->value(), eax);
} else {
@@ -1967,8 +1960,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
return new LStoreKeyedSpecializedArrayElement(external_pointer,
key,
- val,
- temp);
+ val);
}
« src/hydrogen.cc ('K') | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698