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

Unified Diff: src/ia32/lithium-codegen-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-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 46c71e8b1753bdf65d5d385c2bb24770024443eb..1a837431007faa4f0ff52b6d7e5c69293bbb6cec 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -283,7 +283,7 @@ XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
int LCodeGen::ToInteger32(LConstantOperand* op) const {
Handle<Object> value = chunk_->LookupLiteral(op);
- ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
+ ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger());
ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
value->Number());
return static_cast<int32_t>(value->Number());
@@ -294,9 +294,13 @@ Immediate LCodeGen::ToImmediate(LOperand* op) {
LConstantOperand* const_op = LConstantOperand::cast(op);
Handle<Object> literal = chunk_->LookupLiteral(const_op);
Representation r = chunk_->LookupLiteralRepresentation(const_op);
- if (r.IsInteger32()) {
+ if (r.IsInteger()) {
ASSERT(literal->IsNumber());
- return Immediate(static_cast<int32_t>(literal->Number()));
+ if (r.IsClampedRoundedInteger8()) {
+ return Immediate(ClampToUInt8(literal->Number()));
+ } else {
+ return Immediate(static_cast<int32_t>(literal->Number()));
+ }
} else if (r.IsDouble()) {
Abort("unsupported double immediate");
}
@@ -1283,7 +1287,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
int false_block = chunk_->LookupDestination(instr->false_block_id());
Representation r = instr->hydrogen()->representation();
- if (r.IsInteger32()) {
+ if (r.IsInteger()) {
Register reg = ToRegister(instr->InputAt(0));
__ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero);
@@ -2665,7 +2669,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
__ pxor(scratch, scratch);
__ subsd(scratch, input_reg);
__ pand(input_reg, scratch);
- } else if (r.IsInteger32()) {
+ } else if (r.IsInteger()) {
EmitIntegerMathAbs(instr);
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
@@ -2780,7 +2784,7 @@ void LCodeGen::DoPower(LPower* instr) {
__ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
__ CallCFunction(ExternalReference::power_double_double_function(isolate()),
4);
- } else if (exponent_type.IsInteger32()) {
+ } else if (exponent_type.IsInteger()) {
// It is safe to use ebx directly since the instruction is marked
// as a call.
ASSERT(!ToRegister(right).is(ebx));
@@ -3051,21 +3055,8 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
Register value = ToRegister(instr->value());
switch (array_type) {
case kExternalPixelArray: {
- // Clamp the value to [0..255].
- Register temp = ToRegister(instr->TempAt(0));
- // The dec_b below requires that the clamped value is in a byte
- // register. eax is an arbitrary choice to satisfy this requirement, we
- // hinted the register allocator to give us eax when building the
- // instruction.
- ASSERT(temp.is(eax));
- __ mov(temp, ToRegister(instr->value()));
- NearLabel done;
- __ test(temp, Immediate(0xFFFFFF00));
- __ j(zero, &done);
- __ setcc(negative, temp); // 1 if negative, 0 if positive.
- __ dec_b(temp); // 0 if negative, 255 if positive.
- __ bind(&done);
- __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
+ ASSERT(value.is(eax));
+ __ mov_b(Operand(external_pointer, key, times_1, 0), value);
break;
}
case kExternalByteArray:
@@ -3282,7 +3273,7 @@ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
DeferredStringCharFromCode* deferred =
new DeferredStringCharFromCode(this, instr);
- ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
+ ASSERT(instr->hydrogen()->value()->representation().IsInteger());
Register char_code = ToRegister(instr->char_code());
Register result = ToRegister(instr->result());
ASSERT(!char_code.is(result));
@@ -3348,6 +3339,15 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
+void LCodeGen::DoInteger32ToClamped(LInteger32ToClamped* instr) {
+ LOperand* input = instr->InputAt(0);
+ ASSERT(input->IsRegister());
+ Register reg = ToRegister(input);
+ ASSERT(reg.is(ToRegister(instr->result())));
+ __ ClampUInt8(reg);
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI: public LDeferredCode {
public:
@@ -3461,7 +3461,12 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
__ test(ToRegister(input), Immediate(kSmiTagMask));
DeoptimizeIf(not_zero, instr->environment());
}
- __ SmiUntag(ToRegister(input));
+ Register input_reg = ToRegister(input);
+ __ SmiUntag(input_reg);
+
+ if (instr->should_clamp()) {
+ __ ClampUInt8(input_reg);
+ }
}
@@ -3512,14 +3517,30 @@ class DeferredTaggedToI: public LDeferredCode {
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- NearLabel done, heap_number;
+ NearLabel done;
Register input_reg = ToRegister(instr->InputAt(0));
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
factory()->heap_number_map());
- if (instr->truncating()) {
+ Representation r = instr->hydrogen()->representation();
+ if (r.IsClampedRoundedInteger8()) {
+ NearLabel heap_number;
+ __ j(equal, &heap_number);
+ // Check for undefined. Undefined is converted to zero for truncating
+ // conversions.
+ __ cmp(input_reg, factory()->undefined_value());
+ DeoptimizeIf(not_equal, instr->environment());
+ __ mov(input_reg, 0);
+ __ jmp(&done);
+
+ __ bind(&heap_number);
+ XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ __ movdbl(xmm_temp, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __ ClampDoubleToUInt8(xmm_temp, input_reg);
+ } else if (r.IsTruncatedInteger32()) {
+ NearLabel heap_number;
__ j(equal, &heap_number);
// Check for undefined. Undefined is converted to zero for truncating
// conversions.
@@ -3607,6 +3628,10 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
// Smi to int32 conversion
__ SmiUntag(input_reg); // Untag smi.
+ Representation r = instr->hydrogen()->representation();
+ if (r.IsClampedRoundedInteger8()) {
+ __ ClampUInt8(input_reg);
+ }
__ bind(deferred->exit());
}
@@ -3634,7 +3659,10 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
XMMRegister input_reg = ToDoubleRegister(input);
Register result_reg = ToRegister(result);
- if (instr->truncating()) {
+ Representation r = instr->hydrogen()->representation();
+ if (r.IsClampedRoundedInteger8()) {
+ __ ClampDoubleToUInt8(input_reg, result_reg);
+ } else if (r.IsTruncatedInteger32()) {
// Performs a truncating conversion of a floating point number as used by
// the JS bitwise operations.
__ cvttsd2si(result_reg, Operand(input_reg));
« src/hydrogen.cc ('K') | « src/hydrogen-instructions.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698