Revision: 16333
Author: [email protected]
Date: Mon Aug 26 15:30:30 2013 UTC
Log: Get rid of ConvertFieldToDescriptor.
This CL additionally fixes up the attributes for FIELD and CONSTANT in
SetLocalPropertyIgnoreAttributes.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/23252008
http://code.google.com/p/v8/source/detail?r=16333
Modified:
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Aug 26 11:59:14 2013 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Aug 26 15:30:30 2013 UTC
@@ -1865,14 +1865,15 @@
}
-bool JSObject::TooManyFastProperties(int properties,
- JSObject::StoreFromKeyed store_mode) {
+bool JSObject::TooManyFastProperties(StoreFromKeyed store_mode) {
// Allow extra fast properties if the object has more than
- // kFastPropertiesSoftLimit in-object properties. When this is the case,
- // it is very unlikely that the object is being used as a dictionary
- // and there is a good chance that allowing more map transitions
- // will be worth it.
- int inobject = map()->inobject_properties();
+ // kFastPropertiesSoftLimit in-object properties. When this is the case,
it is
+ // very unlikely that the object is being used as a dictionary and there
is a
+ // good chance that allowing more map transitions will be worth it.
+ Map* map = this->map();
+ if (map->unused_property_fields() != 0) return false;
+
+ int inobject = map->inobject_properties();
int limit;
if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
@@ -1880,7 +1881,7 @@
} else {
limit = Max(inobject, kFastPropertiesSoftLimit);
}
- return properties > limit;
+ return properties()->length() > limit;
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Mon Aug 26 11:59:14 2013 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Aug 26 15:30:30 2013 UTC
@@ -1927,7 +1927,8 @@
Object* value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
- ValueType value_type) {
+ ValueType value_type,
+ TransitionFlag flag) {
ASSERT(!IsJSGlobalProxy());
ASSERT(DescriptorArray::kNotFound ==
map()->instance_descriptors()->Search(
@@ -1937,15 +1938,13 @@
// hidden strings) and is not a real identifier.
// Normalize the object if it will have too many fast properties.
Isolate* isolate = GetHeap()->isolate();
- if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name)
- && name != isolate->heap()->hidden_string()) ||
- (map()->unused_property_fields() == 0 &&
- TooManyFastProperties(properties()->length(), store_mode))) {
- Object* obj;
- MaybeObject* maybe_obj =
+ if ((!name->IsSymbol() &&
+ !IsIdentifier(isolate->unicode_cache(), name) &&
+ name != isolate->heap()->hidden_string()) ||
+ TooManyFastProperties(store_mode)) {
+ MaybeObject* maybe_failure =
NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-
+ if (maybe_failure->IsFailure()) return maybe_failure;
return AddSlowProperty(name, value, attributes);
}
@@ -1971,8 +1970,6 @@
properties()->CopySize(properties()->length() + kFieldsAdded);
if (!maybe_values->To(&values)) return maybe_values;
}
-
- TransitionFlag flag = INSERT_TRANSITION;
Heap* heap = isolate->heap();
@@ -2006,7 +2003,8 @@
MaybeObject* JSObject::AddConstantProperty(
Name* name,
Object* constant,
- PropertyAttributes attributes) {
+ PropertyAttributes attributes,
+ TransitionFlag initial_flag) {
// Allocate new instance descriptors with (name, constant) added
ConstantDescriptor d(name, constant, attributes);
@@ -2017,7 +2015,7 @@
// attributes.
attributes != NONE)
? OMIT_TRANSITION
- : INSERT_TRANSITION;
+ : initial_flag;
Map* new_map;
MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
@@ -2077,7 +2075,8 @@
JSReceiver::StoreFromKeyed store_mode,
ExtensibilityCheck extensibility_check,
ValueType value_type,
- StoreMode mode) {
+ StoreMode mode,
+ TransitionFlag transition_flag) {
ASSERT(!IsJSGlobalProxy());
Map* map_of_this = map();
Heap* heap = GetHeap();
@@ -2104,10 +2103,10 @@
// !value->IsTheHole() &&
// !value->IsConsString()) {
if (value->IsJSFunction()) {
- result = AddConstantProperty(name, value, attributes);
+ result = AddConstantProperty(name, value, attributes,
transition_flag);
} else {
result = AddFastProperty(
- name, value, attributes, store_mode, value_type);
+ name, value, attributes, store_mode, value_type,
transition_flag);
}
} else {
// Normalize the object to prevent very large instance descriptors.
@@ -2210,56 +2209,6 @@
return SetNormalizedProperty(name, value, new_details);
}
-
-MaybeObject* JSObject::ConvertDescriptorToField(Name* name,
- Object* new_value,
- PropertyAttributes
attributes,
- TransitionFlag flag) {
- if (map()->unused_property_fields() == 0 &&
- TooManyFastProperties(properties()->length(),
MAY_BE_STORE_FROM_KEYED)) {
- Object* obj;
- MaybeObject* maybe_obj =
NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- return ReplaceSlowProperty(name, new_value, attributes);
- }
-
- Representation representation = IsJSContextExtensionObject()
- ? Representation::Tagged() : new_value->OptimalRepresentation();
- int index = map()->NextFreePropertyIndex();
- FieldDescriptor new_field(name, index, attributes, representation);
-
- // Make a new map for the object.
- Map* new_map;
- MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field,
flag);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-
- // Make new properties array if necessary.
- FixedArray* new_properties = NULL;
- int new_unused_property_fields = map()->unused_property_fields() - 1;
- if (map()->unused_property_fields() == 0) {
- new_unused_property_fields = kFieldsAdded - 1;
- MaybeObject* maybe_new_properties =
- properties()->CopySize(properties()->length() + kFieldsAdded);
- if (!maybe_new_properties->To(&new_properties)) return
maybe_new_properties;
- }
-
- Heap* heap = GetHeap();
- Object* storage;
- MaybeObject* maybe_storage =
- new_value->AllocateNewStorageFor(heap, representation);
- if (!maybe_storage->To(&storage)) return maybe_storage;
-
- // Update pointers to commit changes.
- // Object points to the new map.
- new_map->set_unused_property_fields(new_unused_property_fields);
- set_map(new_map);
- if (new_properties != NULL) {
- set_properties(new_properties);
- }
- FastPropertyAtPut(index, storage);
- return new_value;
-}
-
const char* Representation::Mnemonic() const {
switch (kind_) {
@@ -2407,6 +2356,10 @@
PropertyDetails details = new_descriptors->GetDetails(i);
if (details.type() != FIELD) continue;
PropertyDetails old_details = old_descriptors->GetDetails(i);
+ if (old_details.type() == CALLBACKS) {
+ ASSERT(details.representation().IsTagged());
+ continue;
+ }
ASSERT(old_details.type() == CONSTANT ||
old_details.type() == FIELD);
Object* value = old_details.type() == CONSTANT
@@ -2488,6 +2441,7 @@
MaybeObject* Map::CopyGeneralizeAllRepresentations(
int modify_index,
StoreMode store_mode,
+ PropertyAttributes attributes,
const char* reason) {
Map* new_map;
MaybeObject* maybe_map = this->Copy();
@@ -2501,7 +2455,7 @@
if (store_mode == FORCE_FIELD && details.type() != FIELD) {
FieldDescriptor d(descriptors->GetKey(modify_index),
new_map->NumberOfFields(),
- details.attributes(),
+ attributes,
Representation::Tagged());
d.SetSortedKeyIndex(details.pointer());
descriptors->Set(modify_index, &d);
@@ -2666,8 +2620,8 @@
StoreMode store_mode) {
Map* old_map = this;
DescriptorArray* old_descriptors = old_map->instance_descriptors();
- Representation old_representation =
- old_descriptors->GetDetails(modify_index).representation();
+ PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
+ Representation old_representation = old_details.representation();
// It's fine to transition from None to anything but double without any
// modification to the object, because the default uninitialized value
for
@@ -2686,21 +2640,22 @@
// Check the state of the root map.
if (!old_map->EquivalentToForTransition(root_map)) {
return CopyGeneralizeAllRepresentations(
- modify_index, store_mode, "not equivalent");
+ modify_index, store_mode, old_details.attributes(), "not
equivalent");
}
int verbatim = root_map->NumberOfOwnDescriptors();
if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
return CopyGeneralizeAllRepresentations(
- modify_index, store_mode, "root modification");
+ modify_index, store_mode,
+ old_details.attributes(), "root modification");
}
Map* updated = root_map->FindUpdatedMap(
verbatim, descriptors, old_descriptors);
if (updated == NULL) {
return CopyGeneralizeAllRepresentations(
- modify_index, store_mode, "incompatible");
+ modify_index, store_mode,
old_details.attributes(), "incompatible");
}
DescriptorArray* updated_descriptors = updated->instance_descriptors();
@@ -3816,8 +3771,14 @@
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.type() == CALLBACKS || attributes != details.attributes()) {
- return lookup->holder()->ConvertDescriptorToField(
- *name, *value, attributes);
+ // AddProperty will either normalize the object, or create a new fast
copy
+ // of the map. If we get a fast copy of the map, all field
representations
+ // will be tagged since the transition is omitted.
+ return lookup->holder()->AddProperty(
+ *name, *value, attributes, kNonStrictMode,
+ JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
+ JSReceiver::OMIT_EXTENSIBILITY_CHECK,
+ JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
}
// Keep the target CONSTANT if the same value is stored.
@@ -3880,6 +3841,56 @@
lookup->GetFieldIndex().field_index(), *value);
return *value;
}
+
+
+static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
+ Name* name,
+ Object* value,
+ PropertyAttributes
attributes) {
+ JSObject* object = lookup->holder();
+ if (object->TooManyFastProperties()) {
+ MaybeObject* maybe_failure = object->NormalizeProperties(
+ CLEAR_INOBJECT_PROPERTIES, 0);
+ if (maybe_failure->IsFailure()) return maybe_failure;
+ }
+
+ if (!object->HasFastProperties()) {
+ return object->ReplaceSlowProperty(name, value, attributes);
+ }
+
+ int descriptor_index = lookup->GetDescriptorIndex();
+ if (lookup->GetAttributes() == attributes) {
+ MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
+ descriptor_index, Representation::Tagged(), FORCE_FIELD);
+ if (maybe_failure->IsFailure()) return maybe_failure;
+ } else {
+ Map* map;
+ MaybeObject* maybe_map =
object->map()->CopyGeneralizeAllRepresentations(
+ descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
+ if (!maybe_map->To(&map)) return maybe_map;
+ MaybeObject* maybe_failure = object->MigrateToMap(map);
+ if (maybe_failure->IsFailure()) return maybe_failure;
+ }
+
+ DescriptorArray* descriptors = object->map()->instance_descriptors();
+ int index = descriptors->GetDetails(descriptor_index).field_index();
+ object->FastPropertyAtPut(index, value);
+ return value;
+}
+
+
+static MaybeObject* SetPropertyToFieldWithAttributes(
+ LookupResult* lookup,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ if (lookup->GetAttributes() == attributes) {
+ if (value->IsUninitialized()) return *value;
+ return SetPropertyToField(lookup, name, value);
+ } else {
+ return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
+ }
+}
MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
@@ -4105,25 +4116,41 @@
// Check of IsReadOnly removed from here in clone.
MaybeObject* result = *value;
switch (lookup.type()) {
- case NORMAL: {
- PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
- result = self->SetNormalizedProperty(*name, *value, details);
+ case NORMAL:
+ result = self->ReplaceSlowProperty(*name, *value, attributes);
break;
- }
case FIELD:
- if (value->IsUninitialized()) break;
- result = SetPropertyToField(&lookup, name, value);
+ result = SetPropertyToFieldWithAttributes(
+ &lookup, name, value, attributes);
break;
case CONSTANT:
// Only replace the constant if necessary.
- if (*value == lookup.GetConstant()) return *value;
- if (value->IsUninitialized()) break;
- result = SetPropertyToField(&lookup, name, value);
+ if (lookup.GetAttributes() != attributes ||
+ *value != lookup.GetConstant()) {
+ result = SetPropertyToFieldWithAttributes(
+ &lookup, name, value, attributes);
+ }
break;
case CALLBACKS:
+ // Callbacks are not guaranteed to be installed on the receiver. Also
+ // perform a local lookup again. Fall through.
case INTERCEPTOR:
- // Override callback in clone
- result = self->ConvertDescriptorToField(*name, *value, attributes);
+ self->LocalLookupRealNamedProperty(*name, &lookup);
+ if (lookup.IsFound()) {
+ if (lookup.IsPropertyCallbacks()) {
+ result = ConvertAndSetLocalProperty(
+ &lookup, *name, *value, attributes);
+ } else if (lookup.IsNormal()) {
+ result = self->ReplaceSlowProperty(*name, *value, attributes);
+ } else {
+ result = SetPropertyToFieldWithAttributes(
+ &lookup, name, value, attributes);
+ }
+ } else {
+ result = self->AddProperty(
+ *name, *value, attributes, kNonStrictMode,
MAY_BE_STORE_FROM_KEYED,
+ extensibility_check, value_type, mode);
+ }
break;
case TRANSITION:
result = SetPropertyUsingTransition(&lookup, name, value,
attributes);
=======================================
--- /branches/bleeding_edge/src/objects.h Mon Aug 26 13:04:05 2013 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Aug 26 15:30:30 2013 UTC
@@ -2500,7 +2500,8 @@
MUST_USE_RESULT MaybeObject* AddConstantProperty(
Name* name,
Object* constant,
- PropertyAttributes attributes);
+ PropertyAttributes attributes,
+ TransitionFlag flag);
MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
Name* name,
@@ -2523,14 +2524,6 @@
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind
to_kind);
MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);
- // Converts a descriptor of any other type to a real field, backed by the
- // properties array.
- MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
- Name* name,
- Object* new_value,
- PropertyAttributes attributes,
- TransitionFlag flag = OMIT_TRANSITION);
-
MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map);
MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation(
int modify_index,
@@ -2543,7 +2536,8 @@
Object* value,
PropertyAttributes attributes,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
- ValueType value_type = OPTIMAL_REPRESENTATION);
+ ValueType value_type = OPTIMAL_REPRESENTATION,
+ TransitionFlag flag = INSERT_TRANSITION);
// Add a property to a slow-case object.
MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
@@ -2559,7 +2553,8 @@
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
ValueType value_type = OPTIMAL_REPRESENTATION,
- StoreMode mode = ALLOW_AS_CONSTANT);
+ StoreMode mode = ALLOW_AS_CONSTANT,
+ TransitionFlag flag = INSERT_TRANSITION);
// Convert the object to use the canonical dictionary
// representation. If the object is expected to have additional
properties
@@ -2695,7 +2690,8 @@
// Maximal number of fast properties for the JSObject. Used to
// restrict the number of map transitions to avoid an explosion in
// the number of maps for objects used as dictionaries.
- inline bool TooManyFastProperties(int properties, StoreFromKeyed
store_mode);
+ inline bool TooManyFastProperties(
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
// Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
// Also maximal value of JSArray's length property.
@@ -5631,6 +5627,7 @@
MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations(
int modify_index,
StoreMode store_mode,
+ PropertyAttributes attributes,
const char* reason);
void PrintGeneralization(FILE* file,
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.