Limited the size of transition arrays so they never end up in the large object space.

Also renamed SizeOf on DescriptorArray to LengthOf for consistency.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12196 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2012-07-26 08:27:20 +00:00
parent 6d907fb531
commit 175440898e
3 changed files with 19 additions and 6 deletions

View File

@ -3582,6 +3582,14 @@ Map* Map::elements_transition_map() {
}
bool Map::CanHaveMoreTransitions() {
if (!HasTransitionArray()) return true;
return FixedArray::SizeFor(transitions()->length() +
TransitionArray::kTransitionSize)
<= Page::kMaxNonCodeHeapObjectSize;
}
MaybeObject* Map::AddTransition(String* key, Map* target) {
if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
return TransitionArray::NewWith(key, target);

View File

@ -2120,8 +2120,6 @@ template<RightTrimMode trim_mode>
static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
ASSERT(elms->map() != HEAP->fixed_cow_array_map());
// For now this trick is only applied to fixed arrays in new and paged space.
// In large object space the object's start must coincide with chunk
// and thus the trick is just not applicable.
ASSERT(!HEAP->lo_space()->Contains(elms));
const int len = elms->length();
@ -2217,7 +2215,7 @@ void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
}
// If duplicates were detected, trim the descriptor array to the right size.
int new_array_size = DescriptorArray::SizeFor(new_number_of_descriptors);
int new_array_size = DescriptorArray::LengthFor(new_number_of_descriptors);
if (new_array_size < result->length()) {
RightTrimFixedArray<FROM_MUTATOR>(
isolate->heap(), *result, result->length() - new_array_size);
@ -4883,7 +4881,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
result->SetLastAdded(last_added);
}
if (flag == INSERT_TRANSITION) {
if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
TransitionArray* transitions;
MaybeObject* maybe_transitions = AddTransition(name, result);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
@ -5843,7 +5841,7 @@ MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
}
// Allocate the array of keys.
MaybeObject* maybe_array =
heap->AllocateFixedArray(SizeFor(number_of_descriptors));
heap->AllocateFixedArray(LengthFor(number_of_descriptors));
if (!maybe_array->To(&result)) return maybe_array;
result->set(kEnumCacheIndex, Smi::FromInt(0));

View File

@ -2635,7 +2635,9 @@ class DescriptorArray: public FixedArray {
// fit in a page).
static const int kMaxNumberOfDescriptors = 1024 + 512;
static int SizeFor(int number_of_descriptors) {
// Returns the fixed array length required to hold number_of_descriptors
// descriptors.
static int LengthFor(int number_of_descriptors) {
return ToKeyIndex(number_of_descriptors);
}
@ -4896,6 +4898,11 @@ class Map: public HeapObject {
String* name,
LookupResult* result);
// The size of transition arrays are limited so they do not end up in large
// object space. Otherwise ClearNonLiveTransitions would leak memory while
// applying in-place right trimming.
inline bool CanHaveMoreTransitions();
void SetLastAdded(int index) {
set_bit_field3(LastAddedBits::update(bit_field3(), index));
}