Commit 8f0bf07b authored by ishell's avatar ishell Committed by Commit bot

[runtime] Remove PropertyType definition and use PropertyKind/PropertyLocation instead.

Now we can add a constness bit to the PropertyDetails.

BUG=v8:5495

Review-Url: https://codereview.chromium.org/2629423002
Cr-Commit-Position: refs/heads/master@{#42366}
parent 64963e1b
......@@ -9482,7 +9482,8 @@ bool DescriptorArray::IsEqualUpTo(DescriptorArray* desc, int nof_descriptors) {
}
PropertyDetails details = GetDetails(i);
PropertyDetails other_details = desc->GetDetails(i);
if (details.type() != other_details.type() ||
if (details.kind() != other_details.kind() ||
details.location() != other_details.location() ||
!details.representation().Equals(other_details.representation())) {
return false;
}
......
......@@ -72,18 +72,6 @@ enum PropertyKind { kData = 0, kAccessor = 1 };
// Must fit in the BitField PropertyDetails::LocationField.
enum PropertyLocation { kField = 0, kDescriptor = 1 };
// Order of properties is significant.
// Must fit in the BitField PropertyDetails::TypeField.
// A copy of this is in debug/mirrors.js.
enum PropertyType {
DATA = (kField << 1) | kData,
DATA_CONSTANT = (kDescriptor << 1) | kData,
ACCESSOR = (kField << 1) | kAccessor,
ACCESSOR_CONSTANT = (kDescriptor << 1) | kAccessor
};
class Representation {
public:
enum Kind {
......@@ -298,8 +286,6 @@ class PropertyDetails BASE_EMBEDDED {
PropertyKind kind() const { return KindField::decode(value_); }
PropertyLocation location() const { return LocationField::decode(value_); }
PropertyType type() const { return TypeField::decode(value_); }
PropertyAttributes attributes() const {
return AttributesField::decode(value_);
}
......@@ -348,12 +334,6 @@ class PropertyDetails BASE_EMBEDDED {
: public BitField<uint32_t, 9 + kDescriptorIndexBitCount,
kDescriptorIndexBitCount> {}; // NOLINT
// NOTE: TypeField overlaps with KindField and LocationField.
class TypeField : public BitField<PropertyType, 0, 2> {};
STATIC_ASSERT(KindField::kNext == LocationField::kShift);
STATIC_ASSERT(TypeField::kShift == KindField::kShift);
STATIC_ASSERT(TypeField::kNext == LocationField::kNext);
// All bits for both fast and slow objects must fit in a smi.
STATIC_ASSERT(DictionaryStorageField::kNext <= 31);
STATIC_ASSERT(FieldIndexField::kNext <= 31);
......
......@@ -73,23 +73,12 @@ static Handle<AccessorPair> CreateAccessorPair(bool with_getter,
}
static bool EqualDetails(DescriptorArray* descriptors, int descriptor,
PropertyType type, PropertyAttributes attributes,
Representation representation, int field_index = -1) {
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.type() != type) return false;
if (details.attributes() != attributes) return false;
if (!details.representation().Equals(representation)) return false;
if (field_index >= 0 && details.field_index() != field_index) return false;
return true;
}
class Expectations {
static const int MAX_PROPERTIES = 10;
Isolate* isolate_;
ElementsKind elements_kind_;
PropertyType types_[MAX_PROPERTIES];
PropertyKind kinds_[MAX_PROPERTIES];
PropertyLocation locations_[MAX_PROPERTIES];
PropertyAttributes attributes_[MAX_PROPERTIES];
Representation representations_[MAX_PROPERTIES];
// FieldType for kField, value for DATA_CONSTANT and getter for
......@@ -110,10 +99,12 @@ class Expectations {
isolate,
isolate->object_function()->initial_map()->elements_kind()) {}
void Init(int index, PropertyType type, PropertyAttributes attributes,
Representation representation, Handle<Object> value) {
void Init(int index, PropertyKind kind, PropertyAttributes attributes,
PropertyLocation location, Representation representation,
Handle<Object> value) {
CHECK(index < MAX_PROPERTIES);
types_[index] = type;
kinds_[index] = kind;
locations_[index] = location;
attributes_[index] = attributes;
representations_[index] = representation;
values_[index] = value;
......@@ -125,29 +116,23 @@ class Expectations {
for (int i = 0; i < number_of_properties_; i++) {
os << " " << i << ": ";
os << "Descriptor @ ";
if (types_[i] == ACCESSOR_CONSTANT) {
if (kinds_[i] == kData) {
os << Brief(*values_[i]);
} else {
// kAccessor
os << "(get: " << Brief(*values_[i])
<< ", set: " << Brief(*setter_values_[i]) << ") ";
} else {
os << Brief(*values_[i]);
}
os << " (";
switch (types_[i]) {
case DATA_CONSTANT:
os << "immutable ";
// Fall through.
case DATA:
os << "data";
break;
case ACCESSOR_CONSTANT:
os << "immutable ";
// Fall through.
case ACCESSOR:
os << "accessor";
break;
os << (kinds_[i] == kData ? "data " : "accessor ");
if (locations_[i] == kField) {
os << "field"
<< ": " << representations_[i].Mnemonic();
} else {
os << "descriptor";
}
os << ": " << representations_[i].Mnemonic();
os << ", attrs: " << attributes_[i] << ")\n";
}
os << "\n";
......@@ -159,22 +144,23 @@ class Expectations {
Handle<FieldType> GetFieldType(int index) {
CHECK(index < MAX_PROPERTIES);
CHECK(types_[index] == DATA || types_[index] == ACCESSOR);
CHECK_EQ(kField, locations_[index]);
return Handle<FieldType>::cast(values_[index]);
}
void SetDataField(int index, PropertyAttributes attrs,
Representation representation, Handle<FieldType> value) {
Init(index, DATA, attrs, representation, value);
Representation representation,
Handle<FieldType> field_type) {
Init(index, kData, attrs, kField, representation, field_type);
}
void SetDataField(int index, Representation representation,
Handle<FieldType> value) {
SetDataField(index, attributes_[index], representation, value);
Handle<FieldType> field_type) {
SetDataField(index, attributes_[index], representation, field_type);
}
void SetAccessorField(int index, PropertyAttributes attrs) {
Init(index, ACCESSOR, attrs, Representation::Tagged(),
Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
FieldType::Any(isolate_));
}
......@@ -184,7 +170,7 @@ class Expectations {
void SetDataConstant(int index, PropertyAttributes attrs,
Handle<JSFunction> value) {
Init(index, DATA_CONSTANT, attrs, Representation::HeapObject(), value);
Init(index, kData, attrs, kDescriptor, Representation::HeapObject(), value);
}
void SetDataConstant(int index, Handle<JSFunction> value) {
......@@ -193,14 +179,16 @@ class Expectations {
void SetAccessorConstant(int index, PropertyAttributes attrs,
Handle<Object> getter, Handle<Object> setter) {
Init(index, ACCESSOR_CONSTANT, attrs, Representation::Tagged(), getter);
Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
getter);
setter_values_[index] = setter;
}
void SetAccessorConstantComponent(int index, PropertyAttributes attrs,
AccessorComponent component,
Handle<Object> accessor) {
CHECK_EQ(ACCESSOR_CONSTANT, types_[index]);
CHECK_EQ(kAccessor, kinds_[index]);
CHECK_EQ(kDescriptor, locations_[index]);
CHECK(index < number_of_properties_);
if (component == ACCESSOR_GETTER) {
values_[index] = accessor;
......@@ -230,31 +218,41 @@ class Expectations {
void GeneralizeRepresentation(int index) {
CHECK(index < number_of_properties_);
representations_[index] = Representation::Tagged();
if (types_[index] == DATA || types_[index] == ACCESSOR) {
if (locations_[index] == kField) {
values_[index] = FieldType::Any(isolate_);
}
}
bool Check(DescriptorArray* descriptors, int descriptor) const {
PropertyType type = types_[descriptor];
if (!EqualDetails(descriptors, descriptor, type, attributes_[descriptor],
representations_[descriptor])) {
return false;
}
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.kind() != kinds_[descriptor]) return false;
if (details.location() != locations_[descriptor]) return false;
PropertyAttributes expected_attributes = attributes_[descriptor];
if (details.attributes() != expected_attributes) return false;
Representation expected_representation = representations_[descriptor];
if (!details.representation().Equals(expected_representation)) return false;
Object* value = descriptors->GetValue(descriptor);
Object* expected_value = *values_[descriptor];
switch (type) {
case DATA:
case ACCESSOR: {
if (details.location() == kField) {
if (details.kind() == kData) {
FieldType* type = descriptors->GetFieldType(descriptor);
return FieldType::cast(expected_value) == type;
} else {
// kAccessor
UNREACHABLE();
return false;
}
case DATA_CONSTANT:
} else {
// kDescriptor
if (details.kind() == kData) {
return value == expected_value;
case ACCESSOR_CONSTANT: {
} else {
// kAccessor
if (value == expected_value) return true;
if (!value->IsAccessorPair()) return false;
AccessorPair* pair = AccessorPair::cast(value);
......
......@@ -25,25 +25,6 @@ using namespace v8::internal;
// Helper functions.
//
static void CheckPropertyDetailsFieldsConsistency(PropertyType type,
PropertyKind kind,
PropertyLocation location) {
int type_value = PropertyDetails::TypeField::encode(type);
int kind_location_value = PropertyDetails::KindField::encode(kind) |
PropertyDetails::LocationField::encode(location);
CHECK_EQ(type_value, kind_location_value);
}
TEST(PropertyDetailsFieldsConsistency) {
CheckPropertyDetailsFieldsConsistency(DATA, kData, kField);
CheckPropertyDetailsFieldsConsistency(DATA_CONSTANT, kData, kDescriptor);
CheckPropertyDetailsFieldsConsistency(ACCESSOR, kAccessor, kField);
CheckPropertyDetailsFieldsConsistency(ACCESSOR_CONSTANT, kAccessor,
kDescriptor);
}
TEST(TransitionArray_SimpleFieldTransitions) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment