vendor/v8/src/hydrogen-instructions.cc in mustang-0.0.1 vs vendor/v8/src/hydrogen-instructions.cc in mustang-0.1.0
- old
+ new
@@ -34,10 +34,12 @@
#include "ia32/lithium-ia32.h"
#elif V8_TARGET_ARCH_X64
#include "x64/lithium-x64.h"
#elif V8_TARGET_ARCH_ARM
#include "arm/lithium-arm.h"
+#elif V8_TARGET_ARCH_MIPS
+#include "mips/lithium-mips.h"
#else
#error Unsupported target architecture.
#endif
namespace v8 {
@@ -118,10 +120,48 @@
upper_ = AddWithoutOverflow(upper_, value, &may_overflow);
Verify();
}
+void Range::Intersect(Range* other) {
+ upper_ = Min(upper_, other->upper_);
+ lower_ = Max(lower_, other->lower_);
+ bool b = CanBeMinusZero() && other->CanBeMinusZero();
+ set_can_be_minus_zero(b);
+}
+
+
+void Range::Union(Range* other) {
+ upper_ = Max(upper_, other->upper_);
+ lower_ = Min(lower_, other->lower_);
+ bool b = CanBeMinusZero() || other->CanBeMinusZero();
+ set_can_be_minus_zero(b);
+}
+
+
+void Range::Sar(int32_t value) {
+ int32_t bits = value & 0x1F;
+ lower_ = lower_ >> bits;
+ upper_ = upper_ >> bits;
+ set_can_be_minus_zero(false);
+}
+
+
+void Range::Shl(int32_t value) {
+ int32_t bits = value & 0x1F;
+ int old_lower = lower_;
+ int old_upper = upper_;
+ lower_ = lower_ << bits;
+ upper_ = upper_ << bits;
+ if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
+ upper_ = kMaxInt;
+ lower_ = kMinInt;
+ }
+ set_can_be_minus_zero(false);
+}
+
+
bool Range::AddAndCheckOverflow(Range* other) {
bool may_overflow = false;
lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow);
upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow);
KeepOrder();
@@ -283,28 +323,23 @@
InternalSetOperandAt(index, value);
}
void HValue::ReplaceAndDelete(HValue* other) {
- ReplaceValue(other);
+ if (other != NULL) ReplaceValue(other);
Delete();
}
void HValue::ReplaceValue(HValue* other) {
- ZoneList<HValue*> start_uses(2);
for (int i = 0; i < uses_.length(); ++i) {
- HValue* use = uses_.at(i);
- if (!use->block()->IsStartBlock()) {
- InternalReplaceAtUse(use, other);
- other->uses_.Add(use);
- } else {
- start_uses.Add(use);
- }
+ HValue* use = uses_[i];
+ ASSERT(!use->block()->IsStartBlock());
+ InternalReplaceAtUse(use, other);
+ other->uses_.Add(use);
}
- uses_.Clear();
- uses_.AddAll(start_uses);
+ uses_.Rewind(0);
}
void HValue::ClearOperands() {
for (int i = 0; i < OperandCount(); ++i) {
@@ -379,14 +414,11 @@
void HValue::RegisterUse(int index, HValue* new_value) {
HValue* old_value = OperandAt(index);
if (old_value == new_value) return;
- if (old_value != NULL) {
- ASSERT(old_value->uses_.Contains(this));
- old_value->uses_.RemoveElement(this);
- }
+ if (old_value != NULL) old_value->uses_.RemoveElement(this);
if (new_value != NULL) {
new_value->uses_.Add(this);
}
}
@@ -418,11 +450,13 @@
stream->Add("%s", Mnemonic());
if (HasSideEffects()) stream->Add("*");
stream->Add(" ");
PrintDataTo(stream);
- if (range() != NULL) {
+ if (range() != NULL &&
+ !range()->IsMostGeneric() &&
+ !range()->CanBeMinusZero()) {
stream->Add(" range[%d,%d,m0=%d]",
range()->lower(),
range()->upper(),
static_cast<int>(range()->CanBeMinusZero()));
}
@@ -742,10 +776,12 @@
result->set_can_be_minus_zero(true);
return result;
} else if (representation().IsNone()) {
return NULL;
} else {
+ // Untagged integer32 cannot be -0 and we don't compute ranges for
+ // untagged doubles.
return new Range();
}
}
@@ -753,11 +789,11 @@
if (has_int32_value_) {
Range* result = new Range(int32_value_, int32_value_);
result->set_can_be_minus_zero(false);
return result;
}
- return HInstruction::InferRange();
+ return HValue::InferRange();
}
Range* HPhi::InferRange() {
if (representation().IsInteger32()) {
@@ -787,11 +823,11 @@
}
bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero();
res->set_can_be_minus_zero(m0);
return res;
} else {
- return HArithmeticBinaryOperation::InferRange();
+ return HValue::InferRange();
}
}
Range* HSub::InferRange() {
@@ -803,11 +839,11 @@
ClearFlag(kCanOverflow);
}
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
return res;
} else {
- return HArithmeticBinaryOperation::InferRange();
+ return HValue::InferRange();
}
}
Range* HMul::InferRange() {
@@ -821,11 +857,11 @@
bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
(a->CanBeNegative() && b->CanBeZero());
res->set_can_be_minus_zero(m0);
return res;
} else {
- return HArithmeticBinaryOperation::InferRange();
+ return HValue::InferRange();
}
}
Range* HDiv::InferRange() {
@@ -846,11 +882,11 @@
if (!right()->range()->CanBeZero()) {
ClearFlag(HValue::kCanBeDivByZero);
}
return result;
} else {
- return HArithmeticBinaryOperation::InferRange();
+ return HValue::InferRange();
}
}
Range* HMod::InferRange() {
@@ -863,11 +899,11 @@
if (!right()->range()->CanBeZero()) {
ClearFlag(HValue::kCanBeDivByZero);
}
return result;
} else {
- return HArithmeticBinaryOperation::InferRange();
+ return HValue::InferRange();
}
}
void HPhi::PrintTo(StringStream* stream) {
@@ -894,10 +930,18 @@
SetFlag(kIsArguments);
}
}
+bool HPhi::HasRealUses() {
+ for (int i = 0; i < uses()->length(); i++) {
+ if (!uses()->at(i)->IsPhi()) return true;
+ }
+ return false;
+}
+
+
HValue* HPhi::GetRedundantReplacement() {
HValue* candidate = NULL;
int count = OperandCount();
int position = 0;
while (position < count && candidate == NULL) {
@@ -999,22 +1043,22 @@
HConstant* HConstant::CopyToTruncatedInt32() const {
if (!has_double_value_) return NULL;
int32_t truncated = NumberToInt32(*handle_);
- return new HConstant(Factory::NewNumberFromInt(truncated),
+ return new HConstant(FACTORY->NewNumberFromInt(truncated),
Representation::Integer32());
}
void HConstant::PrintDataTo(StringStream* stream) {
handle()->ShortPrint(stream);
}
bool HArrayLiteral::IsCopyOnWrite() const {
- return constant_elements()->map() == Heap::fixed_cow_array_map();
+ return constant_elements()->map() == HEAP->fixed_cow_array_map();
}
void HBinaryOperation::PrintDataTo(StringStream* stream) {
left()->PrintNameTo(stream);
@@ -1024,80 +1068,64 @@
if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
}
Range* HBitAnd::InferRange() {
- Range* a = left()->range();
- Range* b = right()->range();
- int32_t a_mask = 0xffffffff;
- int32_t b_mask = 0xffffffff;
- if (a != NULL) a_mask = a->Mask();
- if (b != NULL) b_mask = b->Mask();
- int32_t result_mask = a_mask & b_mask;
- if (result_mask >= 0) {
- return new Range(0, result_mask);
- } else {
- return HBinaryOperation::InferRange();
- }
+ int32_t left_mask = (left()->range() != NULL)
+ ? left()->range()->Mask()
+ : 0xffffffff;
+ int32_t right_mask = (right()->range() != NULL)
+ ? right()->range()->Mask()
+ : 0xffffffff;
+ int32_t result_mask = left_mask & right_mask;
+ return (result_mask >= 0)
+ ? new Range(0, result_mask)
+ : HValue::InferRange();
}
Range* HBitOr::InferRange() {
- Range* a = left()->range();
- Range* b = right()->range();
- int32_t a_mask = 0xffffffff;
- int32_t b_mask = 0xffffffff;
- if (a != NULL) a_mask = a->Mask();
- if (b != NULL) b_mask = b->Mask();
- int32_t result_mask = a_mask | b_mask;
- if (result_mask >= 0) {
- return new Range(0, result_mask);
- } else {
- return HBinaryOperation::InferRange();
- }
+ int32_t left_mask = (left()->range() != NULL)
+ ? left()->range()->Mask()
+ : 0xffffffff;
+ int32_t right_mask = (right()->range() != NULL)
+ ? right()->range()->Mask()
+ : 0xffffffff;
+ int32_t result_mask = left_mask | right_mask;
+ return (result_mask >= 0)
+ ? new Range(0, result_mask)
+ : HValue::InferRange();
}
Range* HSar::InferRange() {
if (right()->IsConstant()) {
HConstant* c = HConstant::cast(right());
if (c->HasInteger32Value()) {
- int32_t val = c->Integer32Value();
- Range* result = NULL;
- Range* left_range = left()->range();
- if (left_range == NULL) {
- result = new Range();
- } else {
- result = left_range->Copy();
- }
- result->Sar(val);
+ Range* result = (left()->range() != NULL)
+ ? left()->range()->Copy()
+ : new Range();
+ result->Sar(c->Integer32Value());
return result;
}
}
-
- return HBinaryOperation::InferRange();
+ return HValue::InferRange();
}
Range* HShl::InferRange() {
if (right()->IsConstant()) {
HConstant* c = HConstant::cast(right());
if (c->HasInteger32Value()) {
- int32_t val = c->Integer32Value();
- Range* result = NULL;
- Range* left_range = left()->range();
- if (left_range == NULL) {
- result = new Range();
- } else {
- result = left_range->Copy();
- }
- result->Shl(val);
+ Range* result = (left()->range() != NULL)
+ ? left()->range()->Copy()
+ : new Range();
+ result->Shl(c->Integer32Value());
return result;
}
}
-
- return HBinaryOperation::InferRange();
+ return HValue::InferRange();
}
void HCompare::PrintDataTo(StringStream* stream) {
@@ -1128,10 +1156,64 @@
object()->PrintNameTo(stream);
stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : "");
}
+HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object,
+ ZoneMapList* types,
+ Handle<String> name)
+ : HUnaryOperation(object),
+ types_(Min(types->length(), kMaxLoadPolymorphism)),
+ name_(name),
+ need_generic_(false) {
+ set_representation(Representation::Tagged());
+ SetFlag(kDependsOnMaps);
+ for (int i = 0;
+ i < types->length() && types_.length() < kMaxLoadPolymorphism;
+ ++i) {
+ Handle<Map> map = types->at(i);
+ LookupResult lookup;
+ map->LookupInDescriptors(NULL, *name, &lookup);
+ if (lookup.IsProperty() && lookup.type() == FIELD) {
+ types_.Add(types->at(i));
+ int index = lookup.GetLocalFieldIndexFromMap(*map);
+ if (index < 0) {
+ SetFlag(kDependsOnInobjectFields);
+ } else {
+ SetFlag(kDependsOnBackingStoreFields);
+ }
+ }
+ }
+
+ if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) {
+ SetFlag(kUseGVN);
+ } else {
+ SetAllSideEffects();
+ need_generic_ = true;
+ }
+}
+
+
+bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) {
+ HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value);
+ if (types_.length() != other->types()->length()) return false;
+ if (!name_.is_identical_to(other->name())) return false;
+ if (need_generic_ != other->need_generic_) return false;
+ for (int i = 0; i < types_.length(); i++) {
+ bool found = false;
+ for (int j = 0; j < types_.length(); j++) {
+ if (types_.at(j).is_identical_to(other->types()->at(i))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+}
+
+
void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
stream->Add("[");
key()->PrintNameTo(stream);
stream->Add("]");
@@ -1144,12 +1226,40 @@
key()->PrintNameTo(stream);
stream->Add("]");
}
-void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) {
+void HLoadKeyedSpecializedArrayElement::PrintDataTo(
+ StringStream* stream) {
external_pointer()->PrintNameTo(stream);
+ stream->Add(".");
+ switch (array_type()) {
+ case kExternalByteArray:
+ stream->Add("byte");
+ break;
+ case kExternalUnsignedByteArray:
+ stream->Add("u_byte");
+ break;
+ case kExternalShortArray:
+ stream->Add("short");
+ break;
+ case kExternalUnsignedShortArray:
+ stream->Add("u_short");
+ break;
+ case kExternalIntArray:
+ stream->Add("int");
+ break;
+ case kExternalUnsignedIntArray:
+ stream->Add("u_int");
+ break;
+ case kExternalFloatArray:
+ stream->Add("float");
+ break;
+ case kExternalPixelArray:
+ stream->Add("pixel");
+ break;
+ }
stream->Add("[");
key()->PrintNameTo(stream);
stream->Add("]");
}
@@ -1193,21 +1303,54 @@
stream->Add("] = ");
value()->PrintNameTo(stream);
}
-void HStorePixelArrayElement::PrintDataTo(StringStream* stream) {
+void HStoreKeyedSpecializedArrayElement::PrintDataTo(
+ StringStream* stream) {
external_pointer()->PrintNameTo(stream);
+ stream->Add(".");
+ switch (array_type()) {
+ case kExternalByteArray:
+ stream->Add("byte");
+ break;
+ case kExternalUnsignedByteArray:
+ stream->Add("u_byte");
+ break;
+ case kExternalShortArray:
+ stream->Add("short");
+ break;
+ case kExternalUnsignedShortArray:
+ stream->Add("u_short");
+ break;
+ case kExternalIntArray:
+ stream->Add("int");
+ break;
+ case kExternalUnsignedIntArray:
+ stream->Add("u_int");
+ break;
+ case kExternalFloatArray:
+ stream->Add("float");
+ break;
+ case kExternalPixelArray:
+ stream->Add("pixel");
+ break;
+ }
stream->Add("[");
key()->PrintNameTo(stream);
stream->Add("] = ");
value()->PrintNameTo(stream);
}
-void HLoadGlobal::PrintDataTo(StringStream* stream) {
+void HLoadGlobalCell::PrintDataTo(StringStream* stream) {
stream->Add("[%p]", *cell());
if (check_hole_value()) stream->Add(" (deleteable/read-only)");
+}
+
+
+void HLoadGlobalGeneric::PrintDataTo(StringStream* stream) {
+ stream->Add("%o ", *name());
}
void HStoreGlobal::PrintDataTo(StringStream* stream) {
stream->Add("[%p] = ", *cell());