Tag smi-constants as smi. This also fixes code that copies holes into arrays.

BUG=
R=jkummerow@chromium.org

Review URL: https://chromiumcodereview.appspot.com/15861009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14814 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-05-27 08:43:58 +00:00
parent f2350072bd
commit 3cb8f95c91
9 changed files with 50 additions and 59 deletions

View File

@ -524,7 +524,7 @@ Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
bool LCodeGen::IsInteger32(LConstantOperand* op) const {
return chunk_->LookupLiteralRepresentation(op).IsInteger32();
return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
}

View File

@ -670,11 +670,11 @@ HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
if_nil.Then();
if (continuation.IsFalseReachable()) {
if_nil.Else();
if_nil.Return(graph()->GetConstantSmi0());
if_nil.Return(graph()->GetConstant0());
}
if_nil.End();
return continuation.IsTrueReachable()
? graph()->GetConstantSmi1()
? graph()->GetConstant1()
: graph()->GetConstantUndefined();
}

View File

@ -2079,6 +2079,7 @@ static bool IsInteger32(double value) {
HConstant::HConstant(Handle<Object> handle, Representation r)
: handle_(handle),
unique_id_(),
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
is_internalized_string_(false),
@ -2092,21 +2093,13 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
double n = handle_->Number();
has_int32_value_ = IsInteger32(n);
int32_value_ = DoubleToInt32(n);
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
double_value_ = n;
has_double_value_ = true;
} else {
type_from_value_ = HType::TypeFromValue(handle_);
is_internalized_string_ = handle_->IsInternalizedString();
}
if (r.IsNone()) {
if (has_int32_value_) {
r = Representation::Integer32();
} else if (has_double_value_) {
r = Representation::Double();
} else {
r = Representation::Tagged();
}
}
Initialize(r);
}
@ -2120,6 +2113,7 @@ HConstant::HConstant(Handle<Object> handle,
bool boolean_value)
: handle_(handle),
unique_id_(unique_id),
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
is_internalized_string_(is_internalize_string),
@ -2146,6 +2140,7 @@ HConstant::HConstant(int32_t integer_value,
boolean_value_(integer_value != 0),
int32_value_(integer_value),
double_value_(FastI2D(integer_value)) {
has_smi_value_ = Smi::IsValid(int32_value_);
Initialize(r);
}
@ -2163,11 +2158,21 @@ HConstant::HConstant(double double_value,
boolean_value_(double_value != 0 && !std::isnan(double_value)),
int32_value_(DoubleToInt32(double_value)),
double_value_(double_value) {
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
Initialize(r);
}
void HConstant::Initialize(Representation r) {
if (r.IsNone()) {
if (has_int32_value_) {
r = Representation::Integer32();
} else if (has_double_value_) {
r = Representation::Double();
} else {
r = Representation::Tagged();
}
}
set_representation(r);
SetFlag(kUseGVN);
if (representation().IsInteger32()) {
@ -2177,6 +2182,7 @@ void HConstant::Initialize(Representation r) {
HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
if (r.IsSmi() && !has_smi_value_) return NULL;
if (r.IsInteger32() && !has_int32_value_) return NULL;
if (r.IsDouble() && !has_double_value_) return NULL;
if (has_int32_value_) {

View File

@ -3227,7 +3227,7 @@ class HConstant: public HTemplateInstruction<0> {
return int32_value_;
}
bool HasSmiValue() const {
return HasInteger32Value() && Smi::IsValid(Integer32Value());
return has_smi_value_;
}
bool HasDoubleValue() const { return has_double_value_; }
double DoubleValue() const {
@ -3327,6 +3327,7 @@ class HConstant: public HTemplateInstruction<0> {
// int32_value_ and double_value_ hold valid, safe representations
// of the constant. has_int32_value_ implies has_double_value_ but
// not the converse.
bool has_smi_value_ : 1;
bool has_int32_value_ : 1;
bool has_double_value_ : 1;
bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
@ -3395,6 +3396,16 @@ class HBinaryOperation: public HTemplateInstruction<3> {
virtual Representation RepresentationFromInputs();
virtual void AssumeRepresentation(Representation r);
virtual void UpdateRepresentation(Representation new_rep,
HInferRepresentation* h_infer,
const char* reason) {
// By default, binary operations don't handle Smis.
if (new_rep.IsSmi()) {
new_rep = Representation::Integer32();
}
HValue::UpdateRepresentation(new_rep, h_infer, reason);
}
virtual bool IsCommutative() const { return false; }
virtual void PrintDataTo(StringStream* stream);
@ -3556,22 +3567,13 @@ class HBoundsCheck: public HTemplateInstruction<2> {
// it makes sense to invoke this constructor directly.
HBoundsCheck(HValue* index,
HValue* length,
BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
Representation r = Representation::None())
BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY)
: key_mode_(key_mode), skip_check_(false),
base_(NULL), offset_(0), scale_(0),
responsibility_direction_(DIRECTION_NONE) {
SetOperandAt(0, index);
SetOperandAt(1, length);
if (r.IsNone()) {
// In the normal compilation pipeline the representation is flexible
// (see InferRepresentation).
SetFlag(kFlexibleRepresentation);
} else {
// When compiling stubs we want to set the representation explicitly
// so the compilation pipeline can skip the HInferRepresentation phase.
set_representation(r);
}
SetFlag(kFlexibleRepresentation);
SetFlag(kUseGVN);
}
@ -3718,7 +3720,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
HInferRepresentation* h_infer,
const char* reason) {
// We only generate either int32 or generic tagged bitwise operations.
if (new_rep.IsDouble()) new_rep = Representation::Integer32();
if (new_rep.IsSmi() || new_rep.IsDouble()) {
new_rep = Representation::Integer32();
}
HValue::UpdateRepresentation(new_rep, h_infer, reason);
}

View File

@ -603,19 +603,6 @@ HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer,
}
HConstant* HGraph::GetConstantSmi(SetOncePointer<HConstant>* pointer,
int32_t value) {
if (!pointer->is_set()) {
HConstant* constant =
new(zone()) HConstant(Handle<Object>(Smi::FromInt(value), isolate()),
Representation::Tagged());
constant->InsertAfter(GetConstantUndefined());
pointer->set(constant);
}
return pointer->get();
}
HConstant* HGraph::GetConstant0() {
return GetConstantInt32(&constant_0_, 0);
}
@ -655,16 +642,6 @@ DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
HConstant* HGraph::GetConstantSmi0() {
return GetConstantSmi(&constant_smi_0_, 0);
}
HConstant* HGraph::GetConstantSmi1() {
return GetConstantSmi(&constant_smi_1_, 1);
}
#undef DEFINE_GET_CONSTANT
@ -1562,6 +1539,12 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* context,
}
}
// Since we're about to store a hole value, the store instruction below must
// assume an elements kind that supports heap object values.
if (IsFastSmiOrObjectElementsKind(elements_kind)) {
elements_kind = FAST_HOLEY_ELEMENTS;
}
if (unfold_loop) {
for (int i = 0; i < initial_capacity; i++) {
HInstruction* key = AddInstruction(new(zone)
@ -1608,8 +1591,11 @@ void HGraphBuilder::BuildCopyElements(HValue* context,
from_elements_kind,
ALLOW_RETURN_HOLE));
AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element,
to_elements_kind));
ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind)
? FAST_HOLEY_ELEMENTS : to_elements_kind;
HInstruction* holey_store = AddInstruction(
new(zone()) HStoreKeyed(to_elements, key, element, holey_kind));
holey_store->ClearFlag(HValue::kDeoptimizeOnUndefined);
builder.EndBody();

View File

@ -303,8 +303,6 @@ class HGraph: public ZoneObject {
HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
HConstant* GetConstant0();
HConstant* GetConstant1();
HConstant* GetConstantSmi0();
HConstant* GetConstantSmi1();
HConstant* GetConstantMinus1();
HConstant* GetConstantTrue();
HConstant* GetConstantFalse();
@ -405,8 +403,6 @@ class HGraph: public ZoneObject {
private:
HConstant* GetConstantInt32(SetOncePointer<HConstant>* pointer,
int32_t integer_value);
HConstant* GetConstantSmi(SetOncePointer<HConstant>* pointer,
int32_t integer_value);
void MarkLive(HValue* ref, HValue* instr, ZoneList<HValue*>* worklist);
void MarkLiveInstructions();
@ -439,8 +435,6 @@ class HGraph: public ZoneObject {
SetOncePointer<HConstant> undefined_constant_;
SetOncePointer<HConstant> constant_0_;
SetOncePointer<HConstant> constant_1_;
SetOncePointer<HConstant> constant_smi_0_;
SetOncePointer<HConstant> constant_smi_1_;
SetOncePointer<HConstant> constant_minus1_;
SetOncePointer<HConstant> constant_true_;
SetOncePointer<HConstant> constant_false_;

View File

@ -603,7 +603,7 @@ double LCodeGen::ToDouble(LConstantOperand* op) const {
bool LCodeGen::IsInteger32(LConstantOperand* op) const {
return chunk_->LookupLiteralRepresentation(op).IsInteger32();
return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
}
@ -2127,7 +2127,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
CpuFeatureScope scope(masm(), SSE2);
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32() || r.IsSmi()) {
if (r.IsSmiOrInteger32()) {
Register reg = ToRegister(instr->value());
__ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero);

View File

@ -133,6 +133,7 @@ class Representation {
bool IsSmi() const { return kind_ == kSmi; }
bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
bool IsInteger32() const { return kind_ == kInteger32; }
bool IsSmiOrInteger32() const { return IsSmi() || IsInteger32(); }
bool IsDouble() const { return kind_ == kDouble; }
bool IsHeapObject() const { return kind_ == kHeapObject; }
bool IsExternal() const { return kind_ == kExternal; }

View File

@ -431,7 +431,7 @@ XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const {
return op->IsConstantOperand() &&
chunk_->LookupLiteralRepresentation(op).IsInteger32();
chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
}