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