| Index: src/objects.cc | 
| diff --git a/src/objects.cc b/src/objects.cc | 
| index 053f7107b8e6cb03aac35dac8507dd42d2b09563..1a0a3683b7b5568751aee4310d449549bdc4377c 100644 | 
| --- a/src/objects.cc | 
| +++ b/src/objects.cc | 
| @@ -82,8 +82,24 @@ MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, | 
| constructor = handle(native_context->string_function(), isolate); | 
| } else if (object->IsSymbol()) { | 
| constructor = handle(native_context->symbol_function(), isolate); | 
| -  } else if (object->IsFloat32x4()) { | 
| -    constructor = handle(native_context->float32x4_function(), isolate); | 
| +  } else if (object->IsSimd128Value()) { | 
| +    if (object->IsFloat32x4()) { | 
| +      constructor = handle(native_context->float32x4_function(), isolate); | 
| +    } else if (object->IsInt32x4()) { | 
| +      constructor = handle(native_context->int32x4_function(), isolate); | 
| +    } else if (object->IsBool32x4()) { | 
| +      constructor = handle(native_context->bool32x4_function(), isolate); | 
| +    } else if (object->IsInt16x8()) { | 
| +      constructor = handle(native_context->int16x8_function(), isolate); | 
| +    } else if (object->IsBool16x8()) { | 
| +      constructor = handle(native_context->bool16x8_function(), isolate); | 
| +    } else if (object->IsInt8x16()) { | 
| +      constructor = handle(native_context->int8x16_function(), isolate); | 
| +    } else if (object->IsBool8x16()) { | 
| +      constructor = handle(native_context->bool8x16_function(), isolate); | 
| +    } else { | 
| +      UNREACHABLE(); | 
| +    } | 
| } else { | 
| return MaybeHandle<JSReceiver>(); | 
| } | 
| @@ -100,7 +116,7 @@ bool Object::BooleanValue() { | 
| if (IsUndetectableObject()) return false;   // Undetectable object is false. | 
| if (IsString()) return String::cast(this)->length() != 0; | 
| if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); | 
| -  if (IsFloat32x4()) return true;  // Simd value types always evaluate to true. | 
| +  if (IsSimd128Value()) return true;  // Simd value types evaluate to true. | 
| return true; | 
| } | 
|  | 
| @@ -629,8 +645,24 @@ Map* Object::GetRootMap(Isolate* isolate) { | 
| if (heap_object->IsBoolean()) { | 
| return context->boolean_function()->initial_map(); | 
| } | 
| -  if (heap_object->IsFloat32x4()) { | 
| -    return context->float32x4_function()->initial_map(); | 
| +  if (heap_object->IsSimd128Value()) { | 
| +    if (heap_object->IsFloat32x4()) { | 
| +      return context->float32x4_function()->initial_map(); | 
| +    } else if (heap_object->IsInt32x4()) { | 
| +      return context->int32x4_function()->initial_map(); | 
| +    } else if (heap_object->IsBool32x4()) { | 
| +      return context->bool32x4_function()->initial_map(); | 
| +    } else if (heap_object->IsInt16x8()) { | 
| +      return context->int16x8_function()->initial_map(); | 
| +    } else if (heap_object->IsBool16x8()) { | 
| +      return context->bool16x8_function()->initial_map(); | 
| +    } else if (heap_object->IsInt8x16()) { | 
| +      return context->int8x16_function()->initial_map(); | 
| +    } else if (heap_object->IsBool8x16()) { | 
| +      return context->bool8x16_function()->initial_map(); | 
| +    } else { | 
| +      UNREACHABLE(); | 
| +    } | 
| } | 
| return isolate->heap()->null_value()->map(); | 
| } | 
| @@ -670,14 +702,8 @@ Object* Object::GetSimpleHash() { | 
| uint32_t hash = Oddball::cast(this)->to_string()->Hash(); | 
| return Smi::FromInt(hash); | 
| } | 
| -  if (IsFloat32x4()) { | 
| -    Float32x4* simd = Float32x4::cast(this); | 
| -    uint32_t seed = v8::internal::kZeroHashSeed; | 
| -    uint32_t hash; | 
| -    hash = ComputeIntegerHash(bit_cast<uint32_t>(simd->get_lane(0)), seed); | 
| -    hash = ComputeIntegerHash(bit_cast<uint32_t>(simd->get_lane(1)), hash * 31); | 
| -    hash = ComputeIntegerHash(bit_cast<uint32_t>(simd->get_lane(2)), hash * 31); | 
| -    hash = ComputeIntegerHash(bit_cast<uint32_t>(simd->get_lane(3)), hash * 31); | 
| +  if (IsSimd128Value()) { | 
| +    uint32_t hash = Simd128Value::cast(this)->Hash(); | 
| return Smi::FromInt(hash & Smi::kMaxValue); | 
| } | 
| DCHECK(IsJSReceiver()); | 
| @@ -701,18 +727,37 @@ bool Object::SameValue(Object* other) { | 
| // The object is either a number, a name, an odd-ball, | 
| // a real JS object, or a Harmony proxy. | 
| if (IsNumber() && other->IsNumber()) { | 
| -    return v8::internal::SameValue(Number(), other->Number()); | 
| +    double this_value = Number(); | 
| +    double other_value = other->Number(); | 
| +    // SameValue(NaN, NaN) is true. | 
| +    if (this_value != other_value) { | 
| +      return std::isnan(this_value) && std::isnan(other_value); | 
| +    } | 
| +    // SameValue(0.0, -0.0) is false. | 
| +    return (std::signbit(this_value) == std::signbit(other_value)); | 
| } | 
| if (IsString() && other->IsString()) { | 
| return String::cast(this)->Equals(String::cast(other)); | 
| } | 
| -  if (IsFloat32x4() && other->IsFloat32x4()) { | 
| -    Float32x4* x = Float32x4::cast(this); | 
| -    Float32x4* y = Float32x4::cast(other); | 
| -    return v8::internal::SameValue(x->get_lane(0), y->get_lane(0)) && | 
| -           v8::internal::SameValue(x->get_lane(1), y->get_lane(1)) && | 
| -           v8::internal::SameValue(x->get_lane(2), y->get_lane(2)) && | 
| -           v8::internal::SameValue(x->get_lane(3), y->get_lane(3)); | 
| +  if (IsSimd128Value() && other->IsSimd128Value()) { | 
| +    if (IsFloat32x4() && other->IsFloat32x4()) { | 
| +      Float32x4* a = Float32x4::cast(this); | 
| +      Float32x4* b = Float32x4::cast(other); | 
| +      for (int i = 0; i < 4; i++) { | 
| +        float x = a->get_lane(i); | 
| +        float y = b->get_lane(i); | 
| +        // Implements the ES5 SameValue operation for floating point types. | 
| +        // http://www.ecma-international.org/ecma-262/6.0/#sec-samevalue | 
| +        if (x != y && !(std::isnan(x) && std::isnan(y))) return false; | 
| +        if (std::signbit(x) != std::signbit(y)) return false; | 
| +      } | 
| +      return true; | 
| +    } else { | 
| +      Simd128Value* a = Simd128Value::cast(this); | 
| +      Simd128Value* b = Simd128Value::cast(other); | 
| +      return a->map()->instance_type() == b->map()->instance_type() && | 
| +             a->BitwiseEquals(b); | 
| +    } | 
| } | 
| return false; | 
| } | 
| @@ -724,18 +769,34 @@ bool Object::SameValueZero(Object* other) { | 
| // The object is either a number, a name, an odd-ball, | 
| // a real JS object, or a Harmony proxy. | 
| if (IsNumber() && other->IsNumber()) { | 
| -    return v8::internal::SameValueZero(Number(), other->Number()); | 
| +    double this_value = Number(); | 
| +    double other_value = other->Number(); | 
| +    // +0 == -0 is true | 
| +    return this_value == other_value || | 
| +           (std::isnan(this_value) && std::isnan(other_value)); | 
| } | 
| if (IsString() && other->IsString()) { | 
| return String::cast(this)->Equals(String::cast(other)); | 
| } | 
| -  if (IsFloat32x4() && other->IsFloat32x4()) { | 
| -    Float32x4* x = Float32x4::cast(this); | 
| -    Float32x4* y = Float32x4::cast(other); | 
| -    return v8::internal::SameValueZero(x->get_lane(0), y->get_lane(0)) && | 
| -           v8::internal::SameValueZero(x->get_lane(1), y->get_lane(1)) && | 
| -           v8::internal::SameValueZero(x->get_lane(2), y->get_lane(2)) && | 
| -           v8::internal::SameValueZero(x->get_lane(3), y->get_lane(3)); | 
| +  if (IsSimd128Value() && other->IsSimd128Value()) { | 
| +    if (IsFloat32x4() && other->IsFloat32x4()) { | 
| +      Float32x4* a = Float32x4::cast(this); | 
| +      Float32x4* b = Float32x4::cast(other); | 
| +      for (int i = 0; i < 4; i++) { | 
| +        float x = a->get_lane(i); | 
| +        float y = b->get_lane(i); | 
| +        // Implements the ES6 SameValueZero operation for floating point types. | 
| +        // http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero | 
| +        if (x != y && !(std::isnan(x) && std::isnan(y))) return false; | 
| +        // SameValueZero doesn't distinguish between 0 and -0. | 
| +      } | 
| +      return true; | 
| +    } else { | 
| +      Simd128Value* a = Simd128Value::cast(this); | 
| +      Simd128Value* b = Simd128Value::cast(other); | 
| +      return a->map()->instance_type() == b->map()->instance_type() && | 
| +             a->BitwiseEquals(b); | 
| +    } | 
| } | 
| return false; | 
| } | 
| @@ -1347,12 +1408,27 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT | 
| os << '>'; | 
| break; | 
| } | 
| -    case FLOAT32X4_TYPE: { | 
| -      os << "<Float32x4: "; | 
| -      Float32x4::cast(this)->Float32x4Print(os); | 
| -      os << ">"; | 
| +    case FLOAT32X4_TYPE: | 
| +      os << "<Float32x4>"; | 
| +      break; | 
| +    case INT32X4_TYPE: | 
| +      os << "<Int32x4>"; | 
| +      break; | 
| +    case BOOL32X4_TYPE: | 
| +      os << "<Bool32x4>"; | 
| +      break; | 
| +    case INT16X8_TYPE: | 
| +      os << "<Int16x8>"; | 
| +      break; | 
| +    case BOOL16X8_TYPE: | 
| +      os << "<Bool16x8>"; | 
| +      break; | 
| +    case INT8X16_TYPE: | 
| +      os << "<Int8x16>"; | 
| +      break; | 
| +    case BOOL8X16_TYPE: | 
| +      os << "<Bool8x16>"; | 
| break; | 
| -    } | 
| case JS_PROXY_TYPE: | 
| os << "<JSProxy>"; | 
| break; | 
| @@ -1497,6 +1573,12 @@ void HeapObject::IterateBody(InstanceType type, int object_size, | 
| case HEAP_NUMBER_TYPE: | 
| case MUTABLE_HEAP_NUMBER_TYPE: | 
| case FLOAT32X4_TYPE: | 
| +    case INT32X4_TYPE: | 
| +    case BOOL32X4_TYPE: | 
| +    case INT16X8_TYPE: | 
| +    case BOOL16X8_TYPE: | 
| +    case INT8X16_TYPE: | 
| +    case BOOL8X16_TYPE: | 
| case FILLER_TYPE: | 
| case BYTE_ARRAY_TYPE: | 
| case BYTECODE_ARRAY_TYPE: | 
| @@ -1545,13 +1627,35 @@ void HeapNumber::HeapNumberPrint(std::ostream& os) {  // NOLINT | 
| } | 
|  | 
|  | 
| -void Float32x4::Float32x4Print(std::ostream& os) {  // NOLINT | 
| -  char arr[100]; | 
| -  Vector<char> buffer(arr, arraysize(arr)); | 
| -  os << std::string(DoubleToCString(get_lane(0), buffer)) << ", " | 
| -     << std::string(DoubleToCString(get_lane(1), buffer)) << ", " | 
| -     << std::string(DoubleToCString(get_lane(2), buffer)) << ", " | 
| -     << std::string(DoubleToCString(get_lane(3), buffer)); | 
| +#define FIELD_ADDR_CONST(p, offset) \ | 
| +  (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag) | 
| + | 
| +#define READ_INT32_FIELD(p, offset) \ | 
| +  (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset))) | 
| + | 
| +#define READ_INT64_FIELD(p, offset) \ | 
| +  (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset))) | 
| + | 
| + | 
| +bool Simd128Value::BitwiseEquals(const Simd128Value* other) const { | 
| +  return READ_INT64_FIELD(this, kValueOffset) == | 
| +             READ_INT64_FIELD(other, kValueOffset) && | 
| +         READ_INT64_FIELD(this, kValueOffset + kInt64Size) == | 
| +             READ_INT64_FIELD(other, kValueOffset + kInt64Size); | 
| +} | 
| + | 
| + | 
| +uint32_t Simd128Value::Hash() const { | 
| +  uint32_t seed = v8::internal::kZeroHashSeed; | 
| +  uint32_t hash; | 
| +  hash = ComputeIntegerHash(READ_INT32_FIELD(this, kValueOffset), seed); | 
| +  hash = ComputeIntegerHash( | 
| +      READ_INT32_FIELD(this, kValueOffset + 1 * kInt32Size), hash * 31); | 
| +  hash = ComputeIntegerHash( | 
| +      READ_INT32_FIELD(this, kValueOffset + 2 * kInt32Size), hash * 31); | 
| +  hash = ComputeIntegerHash( | 
| +      READ_INT32_FIELD(this, kValueOffset + 3 * kInt32Size), hash * 31); | 
| +  return hash; | 
| } | 
|  | 
|  | 
|  |