| Index: src/ia32/lithium-ia32.cc
 | 
| ===================================================================
 | 
| --- src/ia32/lithium-ia32.cc	(revision 7683)
 | 
| +++ src/ia32/lithium-ia32.cc	(working copy)
 | 
| @@ -852,24 +852,22 @@
 | 
|      right = UseFixed(right_value, ecx);
 | 
|    }
 | 
|  
 | 
| -  // 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;
 | 
| +  // Shift operations can only deoptimize if we do a logical shift by 0 and
 | 
| +  // the result cannot be truncated to int32.
 | 
| +  bool may_deopt = (op == Token::SHR && constant_value == 0);
 | 
| +  bool does_deopt = false;
 | 
| +  if (may_deopt) {
 | 
| +    for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
 | 
| +      if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
 | 
| +        does_deopt = true;
 | 
|          break;
 | 
|        }
 | 
|      }
 | 
| -    can_deopt = !can_truncate;
 | 
|    }
 | 
|  
 | 
| -  LShiftI* result = new LShiftI(op, left, right, can_deopt);
 | 
| -  return can_deopt
 | 
| -      ? AssignEnvironment(DefineSameAsFirst(result))
 | 
| -      : DefineSameAsFirst(result);
 | 
| +  LInstruction* result =
 | 
| +      DefineSameAsFirst(new LShiftI(op, left, right, does_deopt));
 | 
| +  return does_deopt ? AssignEnvironment(result) : result;
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -1890,8 +1888,11 @@
 | 
|      HLoadKeyedSpecializedArrayElement* instr) {
 | 
|    ExternalArrayType array_type = instr->array_type();
 | 
|    Representation representation(instr->representation());
 | 
| -  ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
 | 
| -         (representation.IsDouble() && array_type == kExternalFloatArray));
 | 
| +  ASSERT(
 | 
| +      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
 | 
| +                                        array_type != kExternalDoubleArray)) ||
 | 
| +      (representation.IsDouble() && (array_type == kExternalFloatArray ||
 | 
| +                                     array_type == kExternalDoubleArray)));
 | 
|    ASSERT(instr->key()->representation().IsInteger32());
 | 
|    LOperand* external_pointer = UseRegister(instr->external_pointer());
 | 
|    LOperand* key = UseRegister(instr->key());
 | 
| @@ -1940,8 +1941,11 @@
 | 
|      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(
 | 
| +      (representation.IsInteger32() && (array_type != kExternalFloatArray &&
 | 
| +                                        array_type != kExternalDoubleArray)) ||
 | 
| +      (representation.IsDouble() && (array_type == kExternalFloatArray ||
 | 
| +                                     array_type == kExternalDoubleArray)));
 | 
|    ASSERT(instr->external_pointer()->representation().IsExternal());
 | 
|    ASSERT(instr->key()->representation().IsInteger32());
 | 
|  
 | 
| @@ -2201,6 +2205,14 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +LInstruction* LChunkBuilder::DoIn(HIn* instr) {
 | 
| +  LOperand* key = UseOrConstantAtStart(instr->key());
 | 
| +  LOperand* object = UseOrConstantAtStart(instr->object());
 | 
| +  LIn* result = new LIn(key, object);
 | 
| +  return MarkAsCall(DefineFixed(result, eax), instr);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  } }  // namespace v8::internal
 | 
|  
 | 
|  #endif  // V8_TARGET_ARCH_IA32
 | 
| 
 |