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

Unified Diff: src/objects.cc

Issue 11035053: Rollback trunk to bleeding_edge revision 12525 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 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-debug.cc » ('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 c37a4a8b2086be48e881634f36f36acf034cc56c..cbef145d971a84c9c601234b0241337b3dae2f2e 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -651,9 +651,11 @@ MaybeObject* Object::GetProperty(Object* receiver,
receiver, result->GetCallbackObject(), name);
case HANDLER:
return result->proxy()->GetPropertyWithHandler(receiver, name);
- case INTERCEPTOR:
+ case INTERCEPTOR: {
+ JSObject* recvr = JSObject::cast(receiver);
return result->holder()->GetPropertyWithInterceptor(
- receiver, name, attributes);
+ recvr, name, attributes);
+ }
case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
@@ -1690,7 +1692,7 @@ MaybeObject* JSObject::AddProperty(String* name,
}
if (HasFastProperties()) {
// Ensure the descriptor array does not get too big.
- if (map_of_this->NumberOfOwnDescriptors() <
+ if (map_of_this->instance_descriptors()->number_of_descriptors() <
DescriptorArray::kMaxNumberOfDescriptors) {
if (value->IsJSFunction()) {
return AddConstantFunctionProperty(name,
@@ -1782,11 +1784,8 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
old_target->SetBackPointer(GetHeap()->undefined_value());
MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
- // Reset the backpointer before returning failure, otherwise the map ends up
- // with an undefined backpointer and no descriptors, losing its own
- // descriptors. Setting the backpointer always succeeds.
- old_target->SetBackPointer(old_map);
if (maybe_failure->IsFailure()) return maybe_failure;
+ old_target->SetBackPointer(old_map);
old_map->set_owns_descriptors(true);
}
@@ -2176,13 +2175,11 @@ enum RightTrimMode { FROM_GC, FROM_MUTATOR };
static void ZapEndOfFixedArray(Address new_end, int to_trim) {
// If we are doing a big trim in old space then we zap the space.
Object** zap = reinterpret_cast<Object**>(new_end);
- zap++; // Header of filler must be at least one word so skip that.
for (int i = 1; i < to_trim; i++) {
*zap++ = Smi::FromInt(0);
}
}
-
template<RightTrimMode trim_mode>
static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
ASSERT(elms->map() != HEAP->fixed_cow_array_map());
@@ -2223,31 +2220,14 @@ static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
}
-void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
- Handle<DescriptorArray> descriptors(map->instance_descriptors());
- if (slack <= descriptors->NumberOfSlackDescriptors()) return;
- int number_of_descriptors = descriptors->number_of_descriptors();
- Isolate* isolate = map->GetIsolate();
- Handle<DescriptorArray> new_descriptors =
- isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
-
- for (int i = 0; i < number_of_descriptors; ++i) {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
- }
-
- Map::SetDescriptors(map, new_descriptors);
-}
-
-
-void Map::AppendCallbackDescriptors(Handle<Map> map,
- Handle<Object> descriptors) {
+void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
+ Handle<Object> descriptors) {
Isolate* isolate = map->GetIsolate();
Handle<DescriptorArray> array(map->instance_descriptors());
- NeanderArray callbacks(descriptors);
+ v8::NeanderArray callbacks(descriptors);
int nof_callbacks = callbacks.length();
-
- ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks);
+ int descriptor_count = array->number_of_descriptors();
+ ASSERT(descriptor_count == map->NumberOfOwnDescriptors());
// Ensure the keys are symbols before writing them into the instance
// descriptor. Since it may cause a GC, it has to be done before we
@@ -2260,23 +2240,51 @@ void Map::AppendCallbackDescriptors(Handle<Map> map,
entry->set_name(*key);
}
- int nof = map->NumberOfOwnDescriptors();
+ Handle<DescriptorArray> result =
+ isolate->factory()->NewDescriptorArray(descriptor_count + nof_callbacks);
+
+ // Ensure that marking will not progress and change color of objects.
+ DescriptorArray::WhitenessWitness witness(*result);
+
+ // Copy the descriptors from the array.
+ for (int i = 0; i < descriptor_count; i++) {
+ result->CopyFrom(i, *array, i, witness);
+ }
+
+ // After this point the GC is not allowed to run anymore until the map is in a
+ // consistent state again, i.e., all the descriptors are appended and the
+ // descriptor array is trimmed to the right size.
+ Map::SetDescriptors(map, result);
// Fill in new callback descriptors. Process the callbacks from
// back to front so that the last callback with a given name takes
// precedence over previously added callbacks with that name.
+ int nof = descriptor_count;
for (int i = nof_callbacks - 1; i >= 0; i--) {
AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i));
String* key = String::cast(entry->name());
// Check if a descriptor with this name already exists before writing.
- if (array->Search(key, nof) == DescriptorArray::kNotFound) {
+ if (result->Search(key, nof) == DescriptorArray::kNotFound) {
CallbacksDescriptor desc(key, entry, entry->property_attributes());
- array->Append(&desc);
+ map->AppendDescriptor(&desc, witness);
nof += 1;
}
}
- map->SetNumberOfOwnDescriptors(nof);
+ ASSERT(nof == map->NumberOfOwnDescriptors());
+
+ // Reinstall the original descriptor array if no new elements were added.
+ if (nof == descriptor_count) {
+ Map::SetDescriptors(map, array);
+ return;
+ }
+
+ // If duplicates were detected, trim the descriptor array to the right size.
+ int new_array_size = DescriptorArray::LengthFor(nof);
+ if (new_array_size < result->length()) {
+ RightTrimFixedArray<FROM_MUTATOR>(
+ isolate->heap(), *result, result->length() - new_array_size);
+ }
}
@@ -3340,7 +3348,8 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
// Allocate new content.
int real_size = map_of_this->NumberOfOwnDescriptors();
- int property_count = real_size;
+ int property_count =
+ map_of_this->NumberOfDescribedProperties(OWN_DESCRIPTORS);
if (expected_additional_properties > 0) {
property_count += expected_additional_properties;
} else {
@@ -5004,45 +5013,32 @@ MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
String* name = descriptor->GetKey();
TransitionArray* transitions;
- MaybeObject* maybe_transitions =
- AddTransition(name, result, SIMPLE_TRANSITION);
+ MaybeObject* maybe_transitions = AddTransition(name, result);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
DescriptorArray* descriptors = instance_descriptors();
int old_size = descriptors->number_of_descriptors();
DescriptorArray* new_descriptors;
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+ DescriptorArray::WhitenessWitness witness(new_descriptors);
- if (descriptors->NumberOfSlackDescriptors() > 0) {
- new_descriptors = descriptors;
- new_descriptors->Append(descriptor);
- } else {
- // Descriptor arrays grow by 50%.
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
- old_size, old_size < 4 ? 1 : old_size / 2);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
-
- DescriptorArray::WhitenessWitness witness(new_descriptors);
-
- // Copy the descriptors, inserting a descriptor.
- for (int i = 0; i < old_size; ++i) {
- new_descriptors->CopyFrom(i, descriptors, i, witness);
- }
-
- new_descriptors->Append(descriptor, witness);
+ for (int i = 0; i < old_size; ++i) {
+ new_descriptors->CopyFrom(i, descriptors, i, witness);
+ }
+ new_descriptors->Append(descriptor, witness, old_size);
- // If the source descriptors had an enum cache we copy it. This ensures that
- // the maps to which we push the new descriptor array back can rely on a
- // cache always being available once it is set. If the map has more
- // enumerated descriptors than available in the original cache, the cache
- // will be lazily replaced by the extended cache when needed.
- if (descriptors->HasEnumCache()) {
- new_descriptors->CopyEnumCacheFrom(descriptors);
- }
+ // If the source descriptors had an enum cache we copy it. This ensures that
+ // the maps to which we push the new descriptor array back can rely on a
+ // cache always being available once it is set. If the map has more
+ // enumerated descriptors than available in the original cache, the cache
+ // will be lazily replaced by the extended cache when needed.
+ if (descriptors->HasEnumCache()) {
+ new_descriptors->CopyEnumCacheFrom(descriptors);
}
transitions->set_descriptors(new_descriptors);
-
set_transitions(transitions);
result->SetBackPointer(this);
set_owns_descriptors(false);
@@ -5056,8 +5052,7 @@ MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
String* name,
- TransitionFlag flag,
- int descriptor_index) {
+ TransitionFlag flag) {
ASSERT(descriptors->IsSortedNoDuplicates());
Map* result;
@@ -5074,11 +5069,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
TransitionArray* transitions;
- SimpleTransitionFlag simple_flag =
- (descriptor_index == descriptors->number_of_descriptors() - 1)
- ? SIMPLE_TRANSITION
- : FULL_TRANSITION;
- MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
+ MaybeObject* maybe_transitions = AddTransition(name, result);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
if (descriptors->IsEmpty()) {
@@ -5183,7 +5174,7 @@ MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
descriptors->CopyUpTo(number_of_own_descriptors);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
- return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
+ return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION);
}
@@ -5195,7 +5186,7 @@ MaybeObject* Map::Copy() {
descriptors->CopyUpTo(number_of_own_descriptors);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
- return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
+ return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION);
}
@@ -5218,7 +5209,7 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
}
DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size, 1);
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
DescriptorArray::WhitenessWitness witness(new_descriptors);
@@ -5228,18 +5219,10 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
new_descriptors->CopyFrom(i, descriptors, i, witness);
}
- if (old_size != descriptors->number_of_descriptors()) {
- new_descriptors->SetNumberOfDescriptors(new_size);
- new_descriptors->Set(old_size, descriptor, witness);
- new_descriptors->Sort();
- } else {
- new_descriptors->Append(descriptor, witness);
- }
+ new_descriptors->Set(old_size, descriptor, witness);
+ new_descriptors->Sort();
- String* key = descriptor->GetKey();
- int insertion_index = new_descriptors->number_of_descriptors() - 1;
-
- return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
+ return CopyReplaceDescriptors(new_descriptors, descriptor->GetKey(), flag);
}
@@ -5315,7 +5298,7 @@ MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor,
// Re-sort if descriptors were removed.
if (new_size != descriptors->length()) new_descriptors->Sort();
- return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
+ return CopyReplaceDescriptors(new_descriptors, key, flag);
}
@@ -6090,17 +6073,16 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
#endif
-MaybeObject* DescriptorArray::Allocate(int number_of_descriptors, int slack) {
+MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
Heap* heap = Isolate::Current()->heap();
// 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 (number_of_descriptors == 0) return heap->empty_descriptor_array();
// Allocate the array of keys.
- MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size));
+ MaybeObject* maybe_array =
+ heap->AllocateFixedArray(LengthFor(number_of_descriptors));
if (!maybe_array->To(&result)) return maybe_array;
- result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
result->set(kEnumCacheIndex, Smi::FromInt(0));
return result;
}
@@ -6117,7 +6099,7 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
if (HasEnumCache()) {
- ASSERT(new_cache->length() > GetEnumCache()->length());
+ ASSERT(new_cache->length() > FixedArray::cast(GetEnumCache())->length());
FixedArray::cast(get(kEnumCacheIndex))->
set(kEnumCacheBridgeCacheIndex, new_cache);
FixedArray::cast(get(kEnumCacheIndex))->
@@ -7390,6 +7372,7 @@ void StringHasher::AddSurrogatePairNoIndex(uc32 c) {
uint32_t StringHasher::GetHashField() {
+ ASSERT(is_valid());
if (length_ <= String::kMaxHashCalcLength) {
if (is_array_index()) {
return MakeArrayIndexHash(array_index(), length_);
@@ -7453,51 +7436,6 @@ static bool ClearBackPointer(Heap* heap, Map* target) {
}
-static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
- int live_enum = map->EnumLength();
- if (live_enum == Map::kInvalidEnumCache) {
- live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
- }
- if (live_enum == 0) return descriptors->ClearEnumCache();
-
- FixedArray* enum_cache = descriptors->GetEnumCache();
-
- int to_trim = enum_cache->length() - live_enum;
- if (to_trim <= 0) return;
- RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim);
-
- if (!descriptors->HasEnumIndicesCache()) return;
- FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
- RightTrimFixedArray<FROM_GC>(heap, enum_indices_cache, to_trim);
-}
-
-
-static void TrimDescriptorArray(Heap* heap,
- Map* map,
- DescriptorArray* descriptors,
- int number_of_own_descriptors) {
- int number_of_descriptors = descriptors->number_of_descriptors();
- int to_trim = number_of_descriptors - number_of_own_descriptors;
- if (to_trim <= 0) return;
-
- // Maximally keep 50% of unused descriptors.
- int keep = Min(to_trim, number_of_own_descriptors / 2);
- for (int i = number_of_own_descriptors;
- i < number_of_own_descriptors + keep;
- ++i) {
- descriptors->EraseDescriptor(heap, i);
- }
-
- if (to_trim > keep) {
- RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep);
- }
- descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
-
- if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
- descriptors->Sort();
-}
-
-
// TODO(mstarzinger): This method should be moved into MarkCompactCollector,
// because it cannot be called from outside the GC and we already have methods
// depending on the transitions layout in the GC anyways.
@@ -7556,7 +7494,28 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
if (descriptors_owner_died) {
if (number_of_own_descriptors > 0) {
- TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
+ int number_of_descriptors = descriptors->number_of_descriptors();
+ int to_trim = number_of_descriptors - number_of_own_descriptors;
+ if (to_trim > 0) {
+ RightTrimFixedArray<FROM_GC>(
+ heap, descriptors, to_trim * DescriptorArray::kDescriptorSize);
+ if (descriptors->HasEnumCache()) {
+ int live_enum =
+ NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
+ if (live_enum == 0) {
+ descriptors->ClearEnumCache();
+ } else {
+ FixedArray* enum_cache =
+ FixedArray::cast(descriptors->GetEnumCache());
+ to_trim = enum_cache->length() - live_enum;
+ if (to_trim > 0) {
+ RightTrimFixedArray<FROM_GC>(
+ heap, FixedArray::cast(descriptors->GetEnumCache()), to_trim);
+ }
+ }
+ }
+ descriptors->Sort();
+ }
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
} else {
t->set_descriptors(heap->empty_descriptor_array());
@@ -7576,8 +7535,8 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
int trim = t->number_of_transitions() - transition_index;
if (trim > 0) {
- RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
- ? trim : trim * TransitionArray::kTransitionSize);
+ RightTrimFixedArray<FROM_GC>(
+ heap, t, trim * TransitionArray::kTransitionSize);
}
}
@@ -10524,7 +10483,7 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
MaybeObject* JSObject::GetPropertyPostInterceptor(
- Object* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10542,7 +10501,7 @@ MaybeObject* JSObject::GetPropertyPostInterceptor(
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- Object* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10556,13 +10515,13 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
MaybeObject* JSObject::GetPropertyWithInterceptor(
- Object* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
Isolate* isolate = GetIsolate();
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope(isolate);
- Handle<Object> receiver_handle(receiver);
+ Handle<JSReceiver> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
@@ -10694,16 +10653,9 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) {
int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
- if (HasFastProperties()) {
- Map* map = this->map();
- if (filter == NONE) return map->NumberOfOwnDescriptors();
- if (filter == DONT_ENUM) {
- int result = map->EnumLength();
- if (result != Map::kInvalidEnumCache) return result;
- }
- return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
- }
- return property_dictionary()->NumberOfElementsFilterAttributes(filter);
+ return HasFastProperties() ?
+ map()->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter) :
+ property_dictionary()->NumberOfElementsFilterAttributes(filter);
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698