Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1356)

Unified Diff: src/objects.cc

Issue 234783002: Handlify Map::CopyDropDescriptors(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more refactoring. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index f66275a3ae46d1f802db1e313190d11a6b201698..6bd75fa2937d968a9c5e0a1c81fd5a722163c32e 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4761,10 +4761,136 @@ void JSObject::TransformToFastProperties(Handle<JSObject> object,
int unused_property_fields) {
if (object->HasFastProperties()) return;
ASSERT(!object->IsGlobalObject());
- CALL_HEAP_FUNCTION_VOID(
- object->GetIsolate(),
- object->property_dictionary()->TransformPropertiesToFastFor(
- *object, unused_property_fields));
+ Isolate* isolate = object->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<NameDictionary> dictionary(object->property_dictionary());
+
+ // Make sure we preserve dictionary representation if there are too many
+ // descriptors.
+ int number_of_elements = dictionary->NumberOfElements();
+ if (number_of_elements > kMaxNumberOfDescriptors) return;
+
+ if (number_of_elements != dictionary->NextEnumerationIndex()) {
+ NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
+ }
+
+ int instance_descriptor_length = 0;
+ int number_of_fields = 0;
+
+ // Compute the length of the instance descriptor.
+ int capacity = dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = dictionary->KeyAt(i);
+ if (dictionary->IsKey(k)) {
+ Object* value = dictionary->ValueAt(i);
+ PropertyType type = dictionary->DetailsAt(i).type();
+ ASSERT(type != FIELD);
+ instance_descriptor_length++;
+ if (type == NORMAL && !value->IsJSFunction()) {
+ number_of_fields += 1;
+ }
+ }
+ }
+
+ int inobject_props = object->map()->inobject_properties();
+
+ // Allocate new map.
+ Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
+ new_map->set_dictionary_map(false);
+
+ if (instance_descriptor_length == 0) {
+ DisallowHeapAllocation no_gc;
+ ASSERT_LE(unused_property_fields, inobject_props);
+ // Transform the object.
+ new_map->set_unused_property_fields(inobject_props);
+ object->set_map(*new_map);
+ object->set_properties(isolate->heap()->empty_fixed_array());
+ // Check that it really works.
+ ASSERT(object->HasFastProperties());
+ return;
+ }
+
+ // Allocate the instance descriptor.
+ Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
+ isolate, instance_descriptor_length);
+
+ int number_of_allocated_fields =
+ number_of_fields + unused_property_fields - inobject_props;
+ if (number_of_allocated_fields < 0) {
+ // There is enough inobject space for all fields (including unused).
+ number_of_allocated_fields = 0;
+ unused_property_fields = inobject_props - number_of_fields;
+ }
+
+ // Allocate the fixed array for the fields.
+ Handle<FixedArray> fields = factory->NewFixedArray(
+ number_of_allocated_fields);
+
+ // Fill in the instance descriptor and the fields.
+ int current_offset = 0;
+ for (int i = 0; i < capacity; i++) {
+ Object* k = dictionary->KeyAt(i);
+ if (dictionary->IsKey(k)) {
+ Object* value = dictionary->ValueAt(i);
+ Handle<Name> key;
+ if (k->IsSymbol()) {
+ key = handle(Symbol::cast(k));
+ } else {
+ // Ensure the key is a unique name before writing into the
+ // instance descriptor.
+ key = factory->InternalizeString(handle(String::cast(k)));
+ }
+
+ PropertyDetails details = dictionary->DetailsAt(i);
+ int enumeration_index = details.dictionary_index();
+ PropertyType type = details.type();
+
+ if (value->IsJSFunction()) {
+ ConstantDescriptor d(key,
+ handle(value, isolate),
+ details.attributes());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else if (type == NORMAL) {
+ if (current_offset < inobject_props) {
+ object->InObjectPropertyAtPut(current_offset,
+ value,
+ UPDATE_WRITE_BARRIER);
+ } else {
+ int offset = current_offset - inobject_props;
+ fields->set(offset, value);
+ }
+ FieldDescriptor d(key,
+ current_offset++,
+ details.attributes(),
+ // TODO(verwaest): value->OptimalRepresentation();
+ Representation::Tagged());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else if (type == CALLBACKS) {
+ CallbacksDescriptor d(key,
+ handle(value, isolate),
+ details.attributes());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else {
+ UNREACHABLE();
+ }
+ }
+ }
+ ASSERT(current_offset == number_of_fields);
+
+ descriptors->Sort();
+
+ DisallowHeapAllocation no_gc;
+ new_map->InitializeDescriptors(*descriptors);
+ new_map->set_unused_property_fields(unused_property_fields);
+
+ // Transform the object.
+ object->set_map(*new_map);
+
+ object->set_properties(*fields);
+ ASSERT(object->IsJSObject());
+
+ // Check that it really works.
+ ASSERT(object->HasFastProperties());
}
@@ -6830,23 +6956,17 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map);
-}
-
-
-MaybeObject* Map::CopyDropDescriptors() {
- Map* result;
- MaybeObject* maybe_result = RawCopy(instance_size());
- if (!maybe_result->To(&result)) return maybe_result;
+ Handle<Map> result = RawCopy(map, map->instance_size());
// Please note instance_type and instance_size are set when allocated.
- result->set_inobject_properties(inobject_properties());
- result->set_unused_property_fields(unused_property_fields());
+ result->set_inobject_properties(map->inobject_properties());
+ result->set_unused_property_fields(map->unused_property_fields());
- result->set_pre_allocated_property_fields(pre_allocated_property_fields());
+ result->set_pre_allocated_property_fields(
+ map->pre_allocated_property_fields());
result->set_is_shared(false);
- result->ClearCodeCache(GetHeap());
- NotifyLeafMapLayoutChange();
+ result->ClearCodeCache(map->GetHeap());
+ map->NotifyLeafMapLayoutChange();
return result;
}
@@ -6869,7 +6989,7 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
if (descriptors->NumberOfSlackDescriptors() == 0) {
int old_size = descriptors->number_of_descriptors();
if (old_size == 0) {
- descriptors = map->GetIsolate()->factory()->NewDescriptorArray(0, 1);
+ descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
} else {
Map::EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
descriptors = handle(map->instance_descriptors());
@@ -7137,7 +7257,7 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
int size = enumeration_index;
Handle<DescriptorArray> descriptors =
- desc->GetIsolate()->factory()->NewDescriptorArray(size, slack);
+ DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
DescriptorArray::WhitenessWitness witness(*descriptors);
if (attributes != NONE) {
@@ -7996,21 +8116,20 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
#endif
-MaybeObject* DescriptorArray::Allocate(Isolate* isolate,
- int number_of_descriptors,
- int slack) {
- Heap* heap = isolate->heap();
+Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
+ int number_of_descriptors,
+ int slack) {
+ ASSERT(0 <= number_of_descriptors);
+ Factory* factory = isolate->factory();
// Do not use DescriptorArray::cast on incomplete object.
int size = number_of_descriptors + slack;
- if (size == 0) return heap->empty_descriptor_array();
- FixedArray* result;
+ if (size == 0) return factory->empty_descriptor_array();
// Allocate the array of keys.
- MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size));
- if (!maybe_array->To(&result)) return maybe_array;
+ Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size));
result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
result->set(kEnumCacheIndex, Smi::FromInt(0));
- return result;
+ return Handle<DescriptorArray>::cast(result);
}
@@ -8074,11 +8193,13 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
// Allocate a new descriptor array large enough to hold the required
// descriptors, with minimally the exact same size as this descriptor array.
- Factory* factory = left_map->GetIsolate()->factory();
+ Isolate* isolate = left_map->GetIsolate();
Handle<DescriptorArray> left(left_map->instance_descriptors());
Handle<DescriptorArray> right(right_map->instance_descriptors());
- Handle<DescriptorArray> result = factory->NewDescriptorArray(
- new_size, Max(new_size, right->number_of_descriptors()) - new_size);
+ Handle<DescriptorArray> result = DescriptorArray::Allocate(
+ isolate,
+ new_size,
+ Max(new_size, right->number_of_descriptors()) - new_size);
ASSERT(result->length() > left->length() ||
result->NumberOfSlackDescriptors() > 0 ||
result->number_of_descriptors() == right->number_of_descriptors());
@@ -11509,10 +11630,7 @@ Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
Factory* factory = map->GetIsolate()->factory();
cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header);
- CALL_AND_RETRY_OR_DIE(map->GetIsolate(),
- map->SetPrototypeTransitions(*cache),
- break,
- return Handle<Map>());
+ Map::SetPrototypeTransitions(map, cache);
}
// Reload number of transitions as GC might shrink them.
@@ -15591,151 +15709,6 @@ Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) {
}
-MaybeObject* NameDictionary::TransformPropertiesToFastFor(
- JSObject* obj, int unused_property_fields) {
- // Make sure we preserve dictionary representation if there are too many
- // descriptors.
- int number_of_elements = NumberOfElements();
- if (number_of_elements > kMaxNumberOfDescriptors) return obj;
-
- if (number_of_elements != NextEnumerationIndex()) {
- MaybeObject* maybe_result = GenerateNewEnumerationIndices();
- if (maybe_result->IsFailure()) return maybe_result;
- }
-
- int instance_descriptor_length = 0;
- int number_of_fields = 0;
-
- Heap* heap = GetHeap();
-
- // Compute the length of the instance descriptor.
- int capacity = Capacity();
- for (int i = 0; i < capacity; i++) {
- Object* k = KeyAt(i);
- if (IsKey(k)) {
- Object* value = ValueAt(i);
- PropertyType type = DetailsAt(i).type();
- ASSERT(type != FIELD);
- instance_descriptor_length++;
- if (type == NORMAL && !value->IsJSFunction()) {
- number_of_fields += 1;
- }
- }
- }
-
- int inobject_props = obj->map()->inobject_properties();
-
- // Allocate new map.
- Map* new_map;
- MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- new_map->set_dictionary_map(false);
-
- if (instance_descriptor_length == 0) {
- ASSERT_LE(unused_property_fields, inobject_props);
- // Transform the object.
- new_map->set_unused_property_fields(inobject_props);
- obj->set_map(new_map);
- obj->set_properties(heap->empty_fixed_array());
- // Check that it really works.
- ASSERT(obj->HasFastProperties());
- return obj;
- }
-
- // Allocate the instance descriptor.
- DescriptorArray* descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(GetIsolate(), instance_descriptor_length);
- if (!maybe_descriptors->To(&descriptors)) {
- return maybe_descriptors;
- }
-
- DescriptorArray::WhitenessWitness witness(descriptors);
-
- int number_of_allocated_fields =
- number_of_fields + unused_property_fields - inobject_props;
- if (number_of_allocated_fields < 0) {
- // There is enough inobject space for all fields (including unused).
- number_of_allocated_fields = 0;
- unused_property_fields = inobject_props - number_of_fields;
- }
-
- // Allocate the fixed array for the fields.
- FixedArray* fields;
- MaybeObject* maybe_fields =
- heap->AllocateFixedArray(number_of_allocated_fields);
- if (!maybe_fields->To(&fields)) return maybe_fields;
-
- // Fill in the instance descriptor and the fields.
- int current_offset = 0;
- for (int i = 0; i < capacity; i++) {
- Object* k = KeyAt(i);
- if (IsKey(k)) {
- Object* value = ValueAt(i);
- Name* key;
- if (k->IsSymbol()) {
- key = Symbol::cast(k);
- } else {
- // Ensure the key is a unique name before writing into the
- // instance descriptor.
- MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
- if (!maybe_key->To(&key)) return maybe_key;
- }
-
- PropertyDetails details = DetailsAt(i);
- int enumeration_index = details.dictionary_index();
- PropertyType type = details.type();
-
- if (value->IsJSFunction()) {
- ConstantDescriptor d(handle(key),
- handle(value, GetIsolate()),
- details.attributes());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else if (type == NORMAL) {
- if (current_offset < inobject_props) {
- obj->InObjectPropertyAtPut(current_offset,
- value,
- UPDATE_WRITE_BARRIER);
- } else {
- int offset = current_offset - inobject_props;
- fields->set(offset, value);
- }
- FieldDescriptor d(handle(key),
- current_offset++,
- details.attributes(),
- // TODO(verwaest): value->OptimalRepresentation();
- Representation::Tagged());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else if (type == CALLBACKS) {
- CallbacksDescriptor d(handle(key),
- handle(value, GetIsolate()),
- details.attributes());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else {
- UNREACHABLE();
- }
- }
- }
- ASSERT(current_offset == number_of_fields);
-
- descriptors->Sort();
-
- new_map->InitializeDescriptors(descriptors);
- new_map->set_unused_property_fields(unused_property_fields);
-
- // Transform the object.
- obj->set_map(new_map);
-
- obj->set_properties(fields);
- ASSERT(obj->IsJSObject());
-
- // Check that it really works.
- ASSERT(obj->HasFastProperties());
-
- return obj;
-}
-
-
Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity(
Handle<ObjectHashTable> table,
int n,
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698