Commit 0b1a9c9e authored by verwaest@chromium.org's avatar verwaest@chromium.org

Free up 11 bits in fast-mode PropertyDetails by removing the enumeration-index.

The descriptors are nowadays ordered in order of addition, so that info was
duplicated.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14571 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 44ec65b1
...@@ -2409,7 +2409,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -2409,7 +2409,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
if (from->HasFastProperties()) { if (from->HasFastProperties()) {
Handle<DescriptorArray> descs = Handle<DescriptorArray> descs =
Handle<DescriptorArray>(from->map()->instance_descriptors()); Handle<DescriptorArray>(from->map()->instance_descriptors());
for (int i = 0; i < descs->number_of_descriptors(); i++) { for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
switch (details.type()) { switch (details.type()) {
case FIELD: { case FIELD: {
...@@ -2443,10 +2443,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -2443,10 +2443,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
// Add to dictionary. // Add to dictionary.
Handle<Name> key = Handle<Name>(descs->GetKey(i)); Handle<Name> key = Handle<Name>(descs->GetKey(i));
Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate()); Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
PropertyDetails d = PropertyDetails(details.attributes(), PropertyDetails d = PropertyDetails(
CALLBACKS, details.attributes(), CALLBACKS, i + 1);
Representation::Tagged(),
details.descriptor_index());
JSObject::SetNormalizedProperty(to, key, callbacks, d); JSObject::SetNormalizedProperty(to, key, callbacks, d);
break; break;
} }
......
...@@ -1309,8 +1309,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { ...@@ -1309,8 +1309,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
if (js_obj->HasFastProperties()) { if (js_obj->HasFastProperties()) {
DescriptorArray* descs = js_obj->map()->instance_descriptors(); DescriptorArray* descs = js_obj->map()->instance_descriptors();
int real_size = js_obj->map()->NumberOfOwnDescriptors(); int real_size = js_obj->map()->NumberOfOwnDescriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) { for (int i = 0; i < real_size; i++) {
if (descs->GetDetails(i).descriptor_index() > real_size) continue;
switch (descs->GetType(i)) { switch (descs->GetType(i)) {
case FIELD: { case FIELD: {
int index = descs->GetFieldIndex(i); int index = descs->GetFieldIndex(i);
......
...@@ -4160,7 +4160,7 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { ...@@ -4160,7 +4160,7 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
ASSERT(name->IsInternalizedString()); ASSERT(name->IsInternalizedString());
// TODO(verwaest): Since we cannot update the boilerplate's map yet, // TODO(verwaest): Since we cannot update the boilerplate's map yet,
// initialize to the worst case. // initialize to the worst case.
FieldDescriptor field(name, i, NONE, Representation::Tagged(), i + 1); FieldDescriptor field(name, i, NONE, Representation::Tagged());
descriptors->Set(i, &field, witness); descriptors->Set(i, &field, witness);
} }
descriptors->Sort(); descriptors->Sort();
...@@ -4589,13 +4589,10 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { ...@@ -4589,13 +4589,10 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
// The global object might be created from an object template with accessors. // The global object might be created from an object template with accessors.
// Fill these accessors into the dictionary. // Fill these accessors into the dictionary.
DescriptorArray* descs = map->instance_descriptors(); DescriptorArray* descs = map->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) { for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
ASSERT(details.type() == CALLBACKS); // Only accessors are expected. ASSERT(details.type() == CALLBACKS); // Only accessors are expected.
PropertyDetails d = PropertyDetails(details.attributes(), PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1);
CALLBACKS,
Representation::None(),
details.descriptor_index());
Object* value = descs->GetCallbacksObject(i); Object* value = descs->GetCallbacksObject(i);
MaybeObject* maybe_value = AllocateJSGlobalPropertyCell(value); MaybeObject* maybe_value = AllocateJSGlobalPropertyCell(value);
if (!maybe_value->ToObject(&value)) return maybe_value; if (!maybe_value->ToObject(&value)) return maybe_value;
......
...@@ -323,10 +323,6 @@ void Map::MapVerify() { ...@@ -323,10 +323,6 @@ void Map::MapVerify() {
instance_size() < HEAP->Capacity())); instance_size() < HEAP->Capacity()));
VerifyHeapPointer(prototype()); VerifyHeapPointer(prototype());
VerifyHeapPointer(instance_descriptors()); VerifyHeapPointer(instance_descriptors());
DescriptorArray* descriptors = instance_descriptors();
for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
CHECK_EQ(i, descriptors->GetDetails(i).descriptor_index() - 1);
}
SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates()); SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
if (HasTransitionArray()) { if (HasTransitionArray()) {
SLOW_ASSERT(transitions()->IsSortedNoDuplicates()); SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
......
...@@ -58,10 +58,7 @@ PropertyDetails::PropertyDetails(Smi* smi) { ...@@ -58,10 +58,7 @@ PropertyDetails::PropertyDetails(Smi* smi) {
Smi* PropertyDetails::AsSmi() { Smi* PropertyDetails::AsSmi() {
// Ensure the upper 2 bits have the same value by sign extending it. This is return Smi::FromInt(value_);
// necessary to be able to use the 31st bit of the property details.
int value = value_ << 1;
return Smi::FromInt(value >> 1);
} }
...@@ -2347,9 +2344,6 @@ void DescriptorArray::Set(int descriptor_number, ...@@ -2347,9 +2344,6 @@ void DescriptorArray::Set(int descriptor_number,
const WhitenessWitness&) { const WhitenessWitness&) {
// Range check. // Range check.
ASSERT(descriptor_number < number_of_descriptors()); ASSERT(descriptor_number < number_of_descriptors());
ASSERT(desc->GetDetails().descriptor_index() <=
number_of_descriptors());
ASSERT(desc->GetDetails().descriptor_index() > 0);
ASSERT(!desc->GetDetails().representation().IsNone()); ASSERT(!desc->GetDetails().representation().IsNone());
NoIncrementalWriteBarrierSet(this, NoIncrementalWriteBarrierSet(this,
...@@ -2367,9 +2361,6 @@ void DescriptorArray::Set(int descriptor_number, ...@@ -2367,9 +2361,6 @@ void DescriptorArray::Set(int descriptor_number,
void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
// Range check. // Range check.
ASSERT(descriptor_number < number_of_descriptors()); ASSERT(descriptor_number < number_of_descriptors());
ASSERT(desc->GetDetails().descriptor_index() <=
number_of_descriptors());
ASSERT(desc->GetDetails().descriptor_index() > 0);
ASSERT(!desc->GetDetails().representation().IsNone()); ASSERT(!desc->GetDetails().representation().IsNone());
set(ToKeyIndex(descriptor_number), desc->GetKey()); set(ToKeyIndex(descriptor_number), desc->GetKey());
...@@ -2381,9 +2372,7 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { ...@@ -2381,9 +2372,7 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
void DescriptorArray::Append(Descriptor* desc, void DescriptorArray::Append(Descriptor* desc,
const WhitenessWitness& witness) { const WhitenessWitness& witness) {
int descriptor_number = number_of_descriptors(); int descriptor_number = number_of_descriptors();
int enumeration_index = descriptor_number + 1;
SetNumberOfDescriptors(descriptor_number + 1); SetNumberOfDescriptors(descriptor_number + 1);
desc->SetEnumerationIndex(enumeration_index);
Set(descriptor_number, desc, witness); Set(descriptor_number, desc, witness);
uint32_t hash = desc->GetKey()->Hash(); uint32_t hash = desc->GetKey()->Hash();
...@@ -2402,9 +2391,7 @@ void DescriptorArray::Append(Descriptor* desc, ...@@ -2402,9 +2391,7 @@ void DescriptorArray::Append(Descriptor* desc,
void DescriptorArray::Append(Descriptor* desc) { void DescriptorArray::Append(Descriptor* desc) {
int descriptor_number = number_of_descriptors(); int descriptor_number = number_of_descriptors();
int enumeration_index = descriptor_number + 1;
SetNumberOfDescriptors(descriptor_number + 1); SetNumberOfDescriptors(descriptor_number + 1);
desc->SetEnumerationIndex(enumeration_index);
Set(descriptor_number, desc); Set(descriptor_number, desc);
uint32_t hash = desc->GetKey()->Hash(); uint32_t hash = desc->GetKey()->Hash();
...@@ -4152,23 +4139,6 @@ static MaybeObject* EnsureHasTransitionArray(Map* map) { ...@@ -4152,23 +4139,6 @@ static MaybeObject* EnsureHasTransitionArray(Map* map) {
void Map::InitializeDescriptors(DescriptorArray* descriptors) { void Map::InitializeDescriptors(DescriptorArray* descriptors) {
int len = descriptors->number_of_descriptors(); int len = descriptors->number_of_descriptors();
#ifdef DEBUG
ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
for (int i = 0; i < len; ++i) used_indices[i] = false;
// Ensure that all enumeration indexes between 1 and length occur uniquely in
// the descriptor array.
for (int i = 0; i < len; ++i) {
int enum_index = descriptors->GetDetails(i).descriptor_index() -
PropertyDetails::kInitialIndex;
ASSERT(0 <= enum_index && enum_index < len);
ASSERT(!used_indices[enum_index]);
used_indices[enum_index] = true;
}
#endif
set_instance_descriptors(descriptors); set_instance_descriptors(descriptors);
SetNumberOfOwnDescriptors(len); SetNumberOfOwnDescriptors(len);
} }
......
This diff is collapsed.
...@@ -154,20 +154,21 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -154,20 +154,21 @@ class PropertyDetails BASE_EMBEDDED {
public: public:
PropertyDetails(PropertyAttributes attributes, PropertyDetails(PropertyAttributes attributes,
PropertyType type, PropertyType type,
Representation representation, int index) {
int index = 0) {
value_ = TypeField::encode(type) value_ = TypeField::encode(type)
| AttributesField::encode(attributes) | AttributesField::encode(attributes)
| RepresentationField::encode(EncodeRepresentation(representation))
| DictionaryStorageField::encode(index); | DictionaryStorageField::encode(index);
ASSERT(type == this->type()); ASSERT(type == this->type());
ASSERT(attributes == this->attributes()); ASSERT(attributes == this->attributes());
if (representation.IsNone()) { }
ASSERT(index == this->dictionary_index());
} else { PropertyDetails(PropertyAttributes attributes,
ASSERT(index == this->descriptor_index()); PropertyType type,
} Representation representation) {
value_ = TypeField::encode(type)
| AttributesField::encode(attributes)
| RepresentationField::encode(EncodeRepresentation(representation));
} }
int pointer() { return DescriptorPointer::decode(value_); } int pointer() { return DescriptorPointer::decode(value_); }
...@@ -183,17 +184,10 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -183,17 +184,10 @@ class PropertyDetails BASE_EMBEDDED {
inline Smi* AsSmi(); inline Smi* AsSmi();
static uint8_t EncodeRepresentation(Representation representation) { static uint8_t EncodeRepresentation(Representation representation) {
ASSERT(representation.kind() <= Representation::kTagged); return representation.kind();
if (representation.kind() < Representation::kInteger32) {
return representation.kind();
} else {
return representation.kind() - 1;
}
} }
static Representation DecodeRepresentation(uint32_t bits) { static Representation DecodeRepresentation(uint32_t bits) {
ASSERT(bits <= Representation::kTagged);
if (bits >= Representation::kInteger32) bits += 1;
return Representation::FromKind(static_cast<Representation::Kind>(bits)); return Representation::FromKind(static_cast<Representation::Kind>(bits));
} }
...@@ -207,10 +201,6 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -207,10 +201,6 @@ class PropertyDetails BASE_EMBEDDED {
return DictionaryStorageField::decode(value_); return DictionaryStorageField::decode(value_);
} }
int descriptor_index() {
return DescriptorStorageField::decode(value_);
}
Representation representation() { Representation representation() {
return DecodeRepresentation(RepresentationField::decode(value_)); return DecodeRepresentation(RepresentationField::decode(value_));
} }
...@@ -232,9 +222,8 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -232,9 +222,8 @@ class PropertyDetails BASE_EMBEDDED {
class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
class DeletedField: public BitField<uint32_t, 6, 1> {}; class DeletedField: public BitField<uint32_t, 6, 1> {};
class DictionaryStorageField: public BitField<uint32_t, 7, 24> {}; class DictionaryStorageField: public BitField<uint32_t, 7, 24> {};
class DescriptorStorageField: public BitField<uint32_t, 7, 11> {}; class DescriptorPointer: public BitField<uint32_t, 7, 11> {};
class DescriptorPointer: public BitField<uint32_t, 18, 11> {}; class RepresentationField: public BitField<uint32_t, 18, 3> {};
class RepresentationField: public BitField<uint32_t, 29, 2> {};
static const int kInitialIndex = 1; static const int kInitialIndex = 1;
......
...@@ -112,7 +112,6 @@ void Descriptor::Print(FILE* out) { ...@@ -112,7 +112,6 @@ void Descriptor::Print(FILE* out) {
GetKey()->ShortPrint(out); GetKey()->ShortPrint(out);
PrintF(out, " @ "); PrintF(out, " @ ");
GetValue()->ShortPrint(out); GetValue()->ShortPrint(out);
PrintF(out, " %d\n", GetDetails().descriptor_index());
} }
......
...@@ -64,11 +64,6 @@ class Descriptor BASE_EMBEDDED { ...@@ -64,11 +64,6 @@ class Descriptor BASE_EMBEDDED {
void Print(FILE* out); void Print(FILE* out);
#endif #endif
void SetEnumerationIndex(int index) {
details_ = PropertyDetails(details_.attributes(), details_.type(),
details_.representation(), index);
}
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); } void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private: private:
...@@ -94,11 +89,10 @@ class Descriptor BASE_EMBEDDED { ...@@ -94,11 +89,10 @@ class Descriptor BASE_EMBEDDED {
Object* value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
PropertyType type, PropertyType type,
Representation representation, Representation representation)
int index)
: key_(key), : key_(key),
value_(value), value_(value),
details_(attributes, type, representation, index) { } details_(attributes, type, representation) { }
friend class DescriptorArray; friend class DescriptorArray;
}; };
...@@ -109,10 +103,9 @@ class FieldDescriptor: public Descriptor { ...@@ -109,10 +103,9 @@ class FieldDescriptor: public Descriptor {
FieldDescriptor(Name* key, FieldDescriptor(Name* key,
int field_index, int field_index,
PropertyAttributes attributes, PropertyAttributes attributes,
Representation representation, Representation representation)
int index = 0)
: Descriptor(key, Smi::FromInt(field_index), attributes, : Descriptor(key, Smi::FromInt(field_index), attributes,
FIELD, representation, index) {} FIELD, representation) {}
}; };
...@@ -120,10 +113,9 @@ class ConstantFunctionDescriptor: public Descriptor { ...@@ -120,10 +113,9 @@ class ConstantFunctionDescriptor: public Descriptor {
public: public:
ConstantFunctionDescriptor(Name* key, ConstantFunctionDescriptor(Name* key,
JSFunction* function, JSFunction* function,
PropertyAttributes attributes, PropertyAttributes attributes)
int index) : Descriptor(key, function, attributes, CONSTANT_FUNCTION,
: Descriptor(key, function, attributes, Representation::Tagged()) {}
CONSTANT_FUNCTION, Representation::Tagged(), index) {}
}; };
...@@ -131,10 +123,9 @@ class CallbacksDescriptor: public Descriptor { ...@@ -131,10 +123,9 @@ class CallbacksDescriptor: public Descriptor {
public: public:
CallbacksDescriptor(Name* key, CallbacksDescriptor(Name* key,
Object* foreign, Object* foreign,
PropertyAttributes attributes, PropertyAttributes attributes)
int index = 0)
: Descriptor(key, foreign, attributes, CALLBACKS, : Descriptor(key, foreign, attributes, CALLBACKS,
Representation::Tagged(), index) {} Representation::Tagged()) {}
}; };
......
...@@ -2316,8 +2316,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) { ...@@ -2316,8 +2316,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
CallbacksDescriptor new_desc(name, CallbacksDescriptor new_desc(name,
instance_desc->GetValue(index), instance_desc->GetValue(index),
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
details.descriptor_index());
// Create a new map featuring the new field descriptors array. // Create a new map featuring the new field descriptors array.
Map* new_map; Map* new_map;
...@@ -2335,7 +2334,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) { ...@@ -2335,7 +2334,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
PropertyDetails new_details( PropertyDetails new_details(
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
details.type(), details.type(),
Representation::None(),
details.dictionary_index()); details.dictionary_index());
function->property_dictionary()->DetailsAtPut(entry, new_details); function->property_dictionary()->DetailsAtPut(entry, new_details);
} }
......
...@@ -350,9 +350,8 @@ void StringStream::PrintUsingMap(JSObject* js_object) { ...@@ -350,9 +350,8 @@ void StringStream::PrintUsingMap(JSObject* js_object) {
} }
int real_size = map->NumberOfOwnDescriptors(); int real_size = map->NumberOfOwnDescriptors();
DescriptorArray* descs = map->instance_descriptors(); DescriptorArray* descs = map->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) { for (int i = 0; i < real_size; i++) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
if (details.descriptor_index() > real_size) continue;
if (details.type() == FIELD) { if (details.type() == FIELD) {
Object* key = descs->GetKey(i); Object* key = descs->GetKey(i);
if (key->IsString() || key->IsNumber()) { if (key->IsString() || key->IsNumber()) {
......
...@@ -142,8 +142,7 @@ TEST(StressJS) { ...@@ -142,8 +142,7 @@ TEST(StressJS) {
CallbacksDescriptor d(*name, CallbacksDescriptor d(*name,
*foreign, *foreign,
static_cast<PropertyAttributes>(0), static_cast<PropertyAttributes>(0));
v8::internal::PropertyDetails::kInitialIndex);
map->AppendDescriptor(&d, witness); map->AppendDescriptor(&d, witness);
// Add the Foo constructor the global object. // Add the Foo constructor the global object.
......
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