diff options
Diffstat (limited to 'deps/v8/src/hydrogen-instructions.cc')
-rw-r--r-- | deps/v8/src/hydrogen-instructions.cc | 196 |
1 files changed, 150 insertions, 46 deletions
diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index db3c3f3f7..0192a763f 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -156,6 +156,20 @@ void Range::Union(Range* other) { } +void Range::CombinedMax(Range* other) { + upper_ = Max(upper_, other->upper_); + lower_ = Max(lower_, other->lower_); + set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero()); +} + + +void Range::CombinedMin(Range* other) { + upper_ = Min(upper_, other->upper_); + lower_ = Min(lower_, other->lower_); + set_can_be_minus_zero(CanBeMinusZero() || other->CanBeMinusZero()); +} + + void Range::Sar(int32_t value) { int32_t bits = value & 0x1F; lower_ = lower_ >> bits; @@ -861,12 +875,14 @@ HValue* HBitwise::Canonicalize() { int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; if (left()->IsConstant() && HConstant::cast(left())->HasInteger32Value() && - HConstant::cast(left())->Integer32Value() == nop_constant) { + HConstant::cast(left())->Integer32Value() == nop_constant && + !right()->CheckFlag(kUint32)) { return right(); } if (right()->IsConstant() && HConstant::cast(right())->HasInteger32Value() && - HConstant::cast(right())->Integer32Value() == nop_constant) { + HConstant::cast(right())->Integer32Value() == nop_constant && + !left()->CheckFlag(kUint32)) { return left(); } return this; @@ -878,7 +894,9 @@ HValue* HBitNot::Canonicalize() { if (value()->IsBitNot()) { HValue* result = HBitNot::cast(value())->value(); ASSERT(result->representation().IsInteger32()); - return result; + if (!result->CheckFlag(kUint32)) { + return result; + } } return this; } @@ -941,7 +959,8 @@ HValue* HUnaryMathOperation::Canonicalize() { // introduced. if (value()->representation().IsInteger32()) return value(); -#ifdef V8_TARGET_ARCH_ARM +#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \ + defined(V8_TARGET_ARCH_X64) if (value()->IsDiv() && (value()->UseCount() == 1)) { // TODO(2038): Implement this optimization for non ARM architectures. HDiv* hdiv = HDiv::cast(value()); @@ -1072,6 +1091,11 @@ void HCheckInstanceType::PrintDataTo(StringStream* stream) { } +void HCheckPrototypeMaps::PrintDataTo(StringStream* stream) { + stream->Add("[receiver_prototype=%p,holder=%p]", *prototype(), *holder()); +} + + void HCallStub::PrintDataTo(StringStream* stream) { stream->Add("%s ", CodeStub::MajorName(major_key_, false)); @@ -1100,6 +1124,7 @@ Range* HChange::InferRange(Zone* zone) { Range* input_range = value()->range(); if (from().IsInteger32() && to().IsTagged() && + !value()->CheckFlag(HInstruction::kUint32) && input_range != NULL && input_range->IsInSmiRange()) { set_type(HType::Smi()); } @@ -1232,6 +1257,24 @@ Range* HMod::InferRange(Zone* zone) { } +Range* HMathMinMax::InferRange(Zone* zone) { + if (representation().IsInteger32()) { + Range* a = left()->range(); + Range* b = right()->range(); + Range* res = a->Copy(zone); + if (operation_ == kMathMax) { + res->CombinedMax(b); + } else { + ASSERT(operation_ == kMathMin); + res->CombinedMin(b); + } + return res; + } else { + return HValue::InferRange(zone); + } +} + + void HPhi::PrintTo(StringStream* stream) { stream->Add("["); for (int i = 0; i < OperandCount(); ++i) { @@ -1346,7 +1389,7 @@ void HPhi::ResetInteger32Uses() { void HSimulate::PrintDataTo(StringStream* stream) { - stream->Add("id=%d", ast_id()); + stream->Add("id=%d", ast_id().ToInt()); if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); if (values_.length() > 0) { if (pop_count_ > 0) stream->Add(" /"); @@ -1375,45 +1418,82 @@ void HDeoptimize::PrintDataTo(StringStream* stream) { void HEnterInlined::PrintDataTo(StringStream* stream) { SmartArrayPointer<char> name = function()->debug_name()->ToCString(); - stream->Add("%s, id=%d", *name, function()->id()); + stream->Add("%s, id=%d", *name, function()->id().ToInt()); +} + + +static bool IsInteger32(double value) { + double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); + return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); } HConstant::HConstant(Handle<Object> handle, Representation r) : handle_(handle), has_int32_value_(false), - has_double_value_(false), - int32_value_(0), - double_value_(0) { + has_double_value_(false) { set_representation(r); SetFlag(kUseGVN); if (handle_->IsNumber()) { double n = handle_->Number(); - double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); - has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); - if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); + has_int32_value_ = IsInteger32(n); + int32_value_ = DoubleToInt32(n); double_value_ = n; has_double_value_ = true; } } +HConstant::HConstant(int32_t integer_value, Representation r) + : has_int32_value_(true), + has_double_value_(true), + int32_value_(integer_value), + double_value_(FastI2D(integer_value)) { + set_representation(r); + SetFlag(kUseGVN); +} + + +HConstant::HConstant(double double_value, Representation r) + : has_int32_value_(IsInteger32(double_value)), + has_double_value_(true), + int32_value_(DoubleToInt32(double_value)), + double_value_(double_value) { + set_representation(r); + SetFlag(kUseGVN); +} + + HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { if (r.IsInteger32() && !has_int32_value_) return NULL; if (r.IsDouble() && !has_double_value_) return NULL; + if (handle_.is_null()) { + ASSERT(has_int32_value_ || has_double_value_); + if (has_int32_value_) return new(zone) HConstant(int32_value_, r); + return new(zone) HConstant(double_value_, r); + } return new(zone) HConstant(handle_, r); } HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { - if (!has_double_value_) return NULL; - int32_t truncated = NumberToInt32(*handle_); - return new(zone) HConstant(FACTORY->NewNumberFromInt(truncated), - Representation::Integer32()); + if (has_int32_value_) { + if (handle_.is_null()) { + return new(zone) HConstant(int32_value_, Representation::Integer32()); + } else { + // Re-use the existing Handle if possible. + return new(zone) HConstant(handle_, Representation::Integer32()); + } + } else if (has_double_value_) { + return new(zone) HConstant(DoubleToInt32(double_value_), + Representation::Integer32()); + } else { + return NULL; + } } -bool HConstant::ToBoolean() const { +bool HConstant::ToBoolean() { // Converts the constant's boolean value according to // ECMAScript section 9.2 ToBoolean conversion. if (HasInteger32Value()) return Integer32Value() != 0; @@ -1421,17 +1501,25 @@ bool HConstant::ToBoolean() const { double v = DoubleValue(); return v != 0 && !isnan(v); } - if (handle()->IsTrue()) return true; - if (handle()->IsFalse()) return false; - if (handle()->IsUndefined()) return false; - if (handle()->IsNull()) return false; - if (handle()->IsString() && - String::cast(*handle())->length() == 0) return false; + Handle<Object> literal = handle(); + if (literal->IsTrue()) return true; + if (literal->IsFalse()) return false; + if (literal->IsUndefined()) return false; + if (literal->IsNull()) return false; + if (literal->IsString() && String::cast(*literal)->length() == 0) { + return false; + } return true; } void HConstant::PrintDataTo(StringStream* stream) { - handle()->ShortPrint(stream); + if (has_int32_value_) { + stream->Add("%d ", int32_value_); + } else if (has_double_value_) { + stream->Add("%f ", FmtElm(double_value_)); + } else { + handle()->ShortPrint(stream); + } } @@ -1638,13 +1726,10 @@ static bool PrototypeChainCanNeverResolve( } LookupResult lookup(isolate); - JSObject::cast(current)->map()->LookupInDescriptors(NULL, *name, &lookup); - if (lookup.IsFound()) { - if (lookup.type() != MAP_TRANSITION) return false; - } else if (!lookup.IsCacheable()) { - return false; - } - + Map* map = JSObject::cast(current)->map(); + map->LookupDescriptor(NULL, *name, &lookup); + if (lookup.IsFound()) return false; + if (!lookup.IsCacheable()) return false; current = JSObject::cast(current)->GetPrototype(); } return true; @@ -1669,7 +1754,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, ++i) { Handle<Map> map = types->at(i); LookupResult lookup(map->GetIsolate()); - map->LookupInDescriptors(NULL, *name, &lookup); + map->LookupDescriptor(NULL, *name, &lookup); if (lookup.IsFound()) { switch (lookup.type()) { case FIELD: { @@ -1685,20 +1770,24 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, case CONSTANT_FUNCTION: types_.Add(types->at(i), zone); break; - case MAP_TRANSITION: - if (!map->has_named_interceptor() && - PrototypeChainCanNeverResolve(map, name)) { - negative_lookups.Add(types->at(i), zone); - } + case CALLBACKS: break; - default: + case TRANSITION: + case INTERCEPTOR: + case NONEXISTENT: + case NORMAL: + case HANDLER: + UNREACHABLE(); break; } - } else if (lookup.IsCacheable()) { - if (!map->has_named_interceptor() && - PrototypeChainCanNeverResolve(map, name)) { - negative_lookups.Add(types->at(i), zone); - } + } else if (lookup.IsCacheable() && + // For dicts the lookup on the map will fail, but the object may + // contain the property so we cannot generate a negative lookup + // (which would just be a map check and return undefined). + !map->is_dictionary_map() && + !map->has_named_interceptor() && + PrototypeChainCanNeverResolve(map, name)) { + negative_lookups.Add(types->at(i), zone); } } @@ -1757,7 +1846,8 @@ void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) { object()->PrintNameTo(stream); stream->Add("["); key()->PrintNameTo(stream); - stream->Add("]"); + stream->Add("] "); + dependency()->PrintNameTo(stream); if (RequiresHoleCheck()) { stream->Add(" check_hole"); } @@ -1782,7 +1872,8 @@ void HLoadKeyedFastDoubleElement::PrintDataTo(StringStream* stream) { elements()->PrintNameTo(stream); stream->Add("["); key()->PrintNameTo(stream); - stream->Add("]"); + stream->Add("] "); + dependency()->PrintNameTo(stream); } @@ -1811,6 +1902,7 @@ HValue* HLoadKeyedGeneric::Canonicalize() { new(block()->zone()) HCheckMapValue(object(), names_cache->map()); HInstruction* index = new(block()->zone()) HLoadKeyedFastElement( index_cache, + key_load->key(), key_load->key()); map_check->InsertBefore(this); index->InsertBefore(this); @@ -1871,7 +1963,8 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo( } stream->Add("["); key()->PrintNameTo(stream); - stream->Add("]"); + stream->Add("] "); + dependency()->PrintNameTo(stream); } @@ -2079,6 +2172,10 @@ HType HPhi::CalculateInferredType() { HType HConstant::CalculateInferredType() { + if (has_int32_value_) { + return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber(); + } + if (has_double_value_) return HType::HeapNumber(); return HType::TypeFromValue(handle_); } @@ -2226,6 +2323,13 @@ HValue* HDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) { } +HValue* HMathFloorOfDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) { + visited->Add(id()); + SetFlag(kBailoutOnMinusZero); + return NULL; +} + + HValue* HMul::EnsureAndPropagateNotMinusZero(BitVector* visited) { visited->Add(id()); if (range() == NULL || range()->CanBeMinusZero()) { |