Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index 3babab3b9a530b798e6c359943e13a48f96f0e56..ea32f9609710d9f615671ce2f065cca0b7377c73 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -29,7 +29,7 @@ |
#include "double.h" |
#include "factory.h" |
-#include "hydrogen.h" |
+#include "hydrogen-infer-representation.h" |
#if V8_TARGET_ARCH_IA32 |
#include "ia32/lithium-ia32.h" |
@@ -80,7 +80,7 @@ void HValue::AssumeRepresentation(Representation r) { |
} |
-void HValue::InferRepresentation(HInferRepresentation* h_infer) { |
+void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
Representation new_rep = RepresentationFromInputs(); |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
@@ -126,7 +126,7 @@ Representation HValue::RepresentationFromUses() { |
void HValue::UpdateRepresentation(Representation new_rep, |
- HInferRepresentation* h_infer, |
+ HInferRepresentationPhase* h_infer, |
const char* reason) { |
Representation r = representation(); |
if (new_rep.is_more_general_than(r)) { |
@@ -141,7 +141,7 @@ void HValue::UpdateRepresentation(Representation new_rep, |
} |
-void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { |
+void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) { |
for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
h_infer->AddToWorklist(it.value()); |
} |
@@ -1152,7 +1152,7 @@ void HBoundsCheck::PrintDataTo(StringStream* stream) { |
} |
-void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { |
+void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
HValue* actual_index = index()->ActualValue(); |
HValue* actual_length = length()->ActualValue(); |
@@ -1227,6 +1227,13 @@ void HCallKnownGlobal::PrintDataTo(StringStream* stream) { |
} |
+void HCallNewArray::PrintDataTo(StringStream* stream) { |
+ stream->Add(ElementsKindToString(elements_kind())); |
+ stream->Add(" "); |
+ HBinaryCall::PrintDataTo(stream); |
+} |
+ |
+ |
void HCallRuntime::PrintDataTo(StringStream* stream) { |
stream->Add("%o ", *name()); |
stream->Add("#%d", argument_count()); |
@@ -1564,7 +1571,7 @@ HValue* HUnaryMathOperation::Canonicalize() { |
HValue* new_right = |
LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); |
if (new_right == NULL && |
-#ifdef V8_TARGET_ARCH_ARM |
+#if V8_TARGET_ARCH_ARM |
CpuFeatures::IsSupported(SUDIV) && |
#endif |
hdiv->observed_input_representation(2).IsSmiOrInteger32()) { |
@@ -1689,6 +1696,14 @@ void HCheckFunction::PrintDataTo(StringStream* stream) { |
} |
+HValue* HCheckFunction::Canonicalize() { |
+ return (value()->IsConstant() && |
+ HConstant::cast(value())->UniqueValueIdsMatch(target_unique_id_)) |
+ ? NULL |
+ : this; |
+} |
+ |
+ |
const char* HCheckInstanceType::GetCheckName() { |
switch (check_) { |
case IS_SPEC_OBJECT: return "object"; |
@@ -1700,6 +1715,7 @@ const char* HCheckInstanceType::GetCheckName() { |
return ""; |
} |
+ |
void HCheckInstanceType::PrintDataTo(StringStream* stream) { |
stream->Add("%s ", GetCheckName()); |
HUnaryOperation::PrintDataTo(stream); |
@@ -2173,6 +2189,7 @@ HConstant::HConstant(Handle<Object> handle, Representation r) |
has_double_value_(false), |
is_internalized_string_(false), |
is_not_in_new_space_(true), |
+ is_cell_(false), |
boolean_value_(handle->BooleanValue()) { |
if (handle_->IsHeapObject()) { |
Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); |
@@ -2189,6 +2206,9 @@ HConstant::HConstant(Handle<Object> handle, Representation r) |
type_from_value_ = HType::TypeFromValue(handle_); |
is_internalized_string_ = handle_->IsInternalizedString(); |
} |
+ |
+ is_cell_ = !handle_.is_null() && |
+ (handle_->IsCell() || handle_->IsPropertyCell()); |
Initialize(r); |
} |
@@ -2199,6 +2219,7 @@ HConstant::HConstant(Handle<Object> handle, |
HType type, |
bool is_internalize_string, |
bool is_not_in_new_space, |
+ bool is_cell, |
bool boolean_value) |
: handle_(handle), |
unique_id_(unique_id), |
@@ -2207,6 +2228,7 @@ HConstant::HConstant(Handle<Object> handle, |
has_double_value_(false), |
is_internalized_string_(is_internalize_string), |
is_not_in_new_space_(is_not_in_new_space), |
+ is_cell_(is_cell), |
boolean_value_(boolean_value), |
type_from_value_(type) { |
ASSERT(!handle.is_null()); |
@@ -2226,6 +2248,7 @@ HConstant::HConstant(int32_t integer_value, |
has_double_value_(true), |
is_internalized_string_(false), |
is_not_in_new_space_(is_not_in_new_space), |
+ is_cell_(false), |
boolean_value_(integer_value != 0), |
int32_value_(integer_value), |
double_value_(FastI2D(integer_value)) { |
@@ -2244,6 +2267,7 @@ HConstant::HConstant(double double_value, |
has_double_value_(true), |
is_internalized_string_(false), |
is_not_in_new_space_(is_not_in_new_space), |
+ is_cell_(false), |
boolean_value_(double_value != 0 && !std::isnan(double_value)), |
int32_value_(DoubleToInt32(double_value)), |
double_value_(double_value) { |
@@ -2266,9 +2290,17 @@ void HConstant::Initialize(Representation r) { |
} |
set_representation(r); |
SetFlag(kUseGVN); |
- if (representation().IsInteger32()) { |
- ClearGVNFlag(kDependsOnOsrEntries); |
+} |
+ |
+ |
+bool HConstant::EmitAtUses() { |
+ ASSERT(IsLinked()); |
+ if (block()->graph()->has_osr()) { |
+ return block()->graph()->IsStandardConstant(this); |
} |
+ if (IsCell()) return false; |
+ if (representation().IsDouble()) return false; |
+ return true; |
} |
@@ -2289,6 +2321,7 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
type_from_value_, |
is_internalized_string_, |
is_not_in_new_space_, |
+ is_cell_, |
boolean_value_); |
} |
@@ -2330,7 +2363,7 @@ void HBinaryOperation::PrintDataTo(StringStream* stream) { |
} |
-void HBinaryOperation::InferRepresentation(HInferRepresentation* h_infer) { |
+void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
Representation new_rep = RepresentationFromInputs(); |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
@@ -2393,7 +2426,7 @@ void HBinaryOperation::AssumeRepresentation(Representation r) { |
} |
-void HMathMinMax::InferRepresentation(HInferRepresentation* h_infer) { |
+void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
Representation new_rep = RepresentationFromInputs(); |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
@@ -2539,7 +2572,7 @@ void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { |
} |
-void HCompareIDAndBranch::AddInformativeDefinitions() { |
+void HCompareNumericAndBranch::AddInformativeDefinitions() { |
NumericRelation r = NumericRelation::FromToken(token()); |
if (r.IsNone()) return; |
@@ -2549,7 +2582,7 @@ void HCompareIDAndBranch::AddInformativeDefinitions() { |
} |
-void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { |
+void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) { |
stream->Add(Token::Name(token())); |
stream->Add(" "); |
left()->PrintNameTo(stream); |
@@ -2572,7 +2605,8 @@ void HGoto::PrintDataTo(StringStream* stream) { |
} |
-void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { |
+void HCompareNumericAndBranch::InferRepresentation( |
+ HInferRepresentationPhase* h_infer) { |
Representation left_rep = left()->representation(); |
Representation right_rep = right()->representation(); |
Representation observed_left = observed_input_representation(0); |
@@ -2593,9 +2627,9 @@ void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { |
// and !=) have special handling of undefined, e.g. undefined == undefined |
// is 'true'. Relational comparisons have a different semantic, first |
// calling ToPrimitive() on their arguments. The standard Crankshaft |
- // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs |
- // are doubles caused 'undefined' to be converted to NaN. That's compatible |
- // out-of-the box with ordered relational comparisons (<, >, <=, |
+ // tagged-to-double conversion to ensure the HCompareNumericAndBranch's |
+ // inputs are doubles caused 'undefined' to be converted to NaN. That's |
+ // compatible out-of-the box with ordered relational comparisons (<, >, <=, |
// >=). However, for equality comparisons (and for 'in' and 'instanceof'), |
// it is not consistent with the spec. For example, it would cause undefined |
// == undefined (should be true) to be evaluated as NaN == NaN |
@@ -3076,6 +3110,11 @@ HType HCheckHeapObject::CalculateInferredType() { |
} |
+HType HCheckSmi::CalculateInferredType() { |
+ return HType::Smi(); |
+} |
+ |
+ |
HType HPhi::CalculateInferredType() { |
HType result = HType::Uninitialized(); |
for (int i = 0; i < OperandCount(); ++i) { |
@@ -3677,7 +3716,7 @@ void HPhi::SimplifyConstantInputs() { |
} |
-void HPhi::InferRepresentation(HInferRepresentation* h_infer) { |
+void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
Representation new_rep = RepresentationFromInputs(); |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
@@ -3822,6 +3861,13 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map, |
} |
+HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { |
+ return HObjectAccess( |
+ kInobject, Cell::kValueOffset, |
+ Handle<String>(isolate->heap()->cell_value_string())); |
+} |
+ |
+ |
void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { |
// set the appropriate GVN flags for a given load or store instruction |
if (is_store) { |