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

Unified Diff: src/heap.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
===================================================================
--- src/heap.cc (revision 8618)
+++ src/heap.cc (working copy)
@@ -33,6 +33,7 @@
#include "codegen.h"
#include "compilation-cache.h"
#include "debug.h"
+#include "deoptimizer.h"
#include "global-handles.h"
#include "heap-profiler.h"
#include "incremental-marking.h"
@@ -95,6 +96,7 @@
// Will be 4 * reserved_semispace_size_ to ensure that young
// generation can be aligned to its size.
survived_since_last_expansion_(0),
+ sweep_generation_(0),
always_allocate_scope_depth_(0),
linear_allocation_scope_depth_(0),
contexts_disposed_(0),
@@ -107,6 +109,7 @@
cell_space_(NULL),
lo_space_(NULL),
gc_state_(NOT_IN_GC),
+ gc_post_processing_depth_(0),
ms_count_(0),
gc_count_(0),
unflattened_strings_length_(0),
@@ -155,6 +158,15 @@
max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
#endif
+ intptr_t max_virtual = OS::MaxVirtualMemory();
+
+ if (max_virtual > 0) {
+ if (code_range_size_ > 0) {
+ // Reserve no more than 1/8 of the memory for the code range.
+ code_range_size_ = Min(code_range_size_, max_virtual >> 3);
+ }
+ }
+
memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
global_contexts_list_ = NULL;
mark_compact_collector_.heap_ = this;
@@ -512,7 +524,6 @@
GarbageCollectionEpilogue();
}
-
ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped());
if (incremental_marking()->IsStopped()) {
if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) {
@@ -520,10 +531,6 @@
}
}
-#ifdef ENABLE_LOGGING_AND_PROFILING
- if (FLAG_log_gc) HeapProfiler::WriteSample();
-#endif
-
return next_gc_likely_to_collect_more;
}
@@ -721,7 +728,7 @@
if (collector == MARK_COMPACTOR) {
// Perform mark-sweep with optional compaction.
MarkCompact(tracer);
-
+ sweep_generation_++;
bool high_survival_rate_during_scavenges = IsHighSurvivalRate() &&
IsStableOrIncreasingSurvivalTrend();
@@ -760,11 +767,13 @@
isolate_->counters()->objs_since_last_young()->Set(0);
+ gc_post_processing_depth_++;
{ DisableAssertNoAllocation allow_allocation;
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
next_gc_likely_to_collect_more =
isolate_->global_handles()->PostGarbageCollectionProcessing(collector);
}
+ gc_post_processing_depth_--;
// Update relocatables.
Relocatable::PostGarbageCollectionProcessing();
@@ -831,6 +840,9 @@
// TODO(gc) select heuristic for flushing NumberString cache with
// FlushNumberStringCache
+ if (FLAG_cleanup_code_caches_at_gc) {
+ polymorphic_code_cache()->set_cache(undefined_value());
+ }
ClearNormalizedMapCaches();
}
@@ -1064,9 +1076,10 @@
scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
- isolate_->global_handles()->IdentifyWeakIndependentHandles(
+ isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
&IsUnscavengedHeapObject);
- isolate_->global_handles()->IterateWeakIndependentRoots(&scavenge_visitor);
+ isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
+ &scavenge_visitor);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
@@ -1332,6 +1345,7 @@
table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
table_.Register(kVisitByteArray, &EvacuateByteArray);
table_.Register(kVisitFixedArray, &EvacuateFixedArray);
+ table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
table_.Register(kVisitGlobalContext,
&ObjectEvacuationStrategy<POINTER_OBJECT>::
@@ -1345,6 +1359,10 @@
&ObjectEvacuationStrategy<POINTER_OBJECT>::
template VisitSpecialized<SharedFunctionInfo::kSize>);
+ table_.Register(kVisitJSRegExp,
+ &ObjectEvacuationStrategy<POINTER_OBJECT>::
+ Visit);
+
table_.Register(kVisitJSFunction,
&ObjectEvacuationStrategy<POINTER_OBJECT>::
template VisitSpecialized<JSFunction::kSize>);
@@ -1489,6 +1507,18 @@
}
+ static inline void EvacuateFixedDoubleArray(Map* map,
+ HeapObject** slot,
+ HeapObject* object) {
+ int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
+ int object_size = FixedDoubleArray::SizeFor(length);
+ EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map,
+ slot,
+ object,
+ object_size);
+ }
+
+
static inline void EvacuateByteArray(Map* map,
HeapObject** slot,
HeapObject* object) {
@@ -1606,7 +1636,6 @@
bool logging_and_profiling = false;
#endif
-
if (!incremental_marking()->IsMarking()) {
if (!logging_and_profiling) {
scavenging_visitors_table_.CopyFrom(
@@ -1683,7 +1712,8 @@
map->set_prototype_transitions(empty_fixed_array());
map->set_unused_property_fields(0);
map->set_bit_field(0);
- map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements));
+ map->set_bit_field2(1 << Map::kIsExtensible);
+ map->set_elements_kind(JSObject::FAST_ELEMENTS);
// If the map object is aligned fill the padding area with Smi 0 objects.
if (Map::kPadStart < Map::kSize) {
@@ -1707,6 +1737,11 @@
}
+MaybeObject* Heap::AllocatePolymorphicCodeCache() {
+ return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
+}
+
+
const Heap::StringTypeTable Heap::string_type_table[] = {
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
{type, size, k##camel_name##MapRootIndex},
@@ -1832,6 +1867,12 @@
Map::cast(obj)->set_is_undetectable();
{ MaybeObject* maybe_obj =
+ AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ set_fixed_double_array_map(Map::cast(obj));
+
+ { MaybeObject* maybe_obj =
AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
@@ -1896,6 +1937,12 @@
}
set_external_float_array_map(Map::cast(obj));
+ { MaybeObject* maybe_obj =
+ AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ set_non_strict_arguments_elements_map(Map::cast(obj));
+
{ MaybeObject* maybe_obj = AllocateMap(EXTERNAL_DOUBLE_ARRAY_TYPE,
ExternalArray::kAlignedSize);
if (!maybe_obj->ToObject(&obj)) return false;
@@ -1941,7 +1988,7 @@
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
- set_context_map(Map::cast(obj));
+ set_function_context_map(Map::cast(obj));
{ MaybeObject* maybe_obj =
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
@@ -1953,6 +2000,12 @@
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
+ set_with_context_map(Map::cast(obj));
+
+ { MaybeObject* maybe_obj =
+ AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
Map* global_context_map = Map::cast(obj);
global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext);
set_global_context_map(global_context_map);
@@ -2220,6 +2273,11 @@
}
set_non_monomorphic_cache(NumberDictionary::cast(obj));
+ { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache();
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj));
+
set_instanceof_cache_function(Smi::FromInt(0));
set_instanceof_cache_map(Smi::FromInt(0));
set_instanceof_cache_answer(Smi::FromInt(0));
@@ -2469,7 +2527,7 @@
share->set_num_literals(0);
share->set_end_position(0);
share->set_function_token_position(0);
- share->set_es5_native(false);
+ share->set_native(false);
return result;
}
@@ -2660,12 +2718,13 @@
MaybeObject* Heap::AllocateSubString(String* buffer,
- int start,
- int end,
- PretenureFlag pretenure) {
+ int start,
+ int end,
+ PretenureFlag pretenure) {
int length = end - start;
-
- if (length == 1) {
+ if (length == 0) {
+ return empty_string();
+ } else if (length == 1) {
return LookupSingleCharacterStringFromCode(buffer->Get(start));
} else if (length == 2) {
// Optimization for 2-byte strings often used as keys in a decompression
@@ -3005,9 +3064,6 @@
if (!maybe_result->ToObject(&result)) return maybe_result;
}
HeapObject::cast(result)->set_map(map);
-#ifdef ENABLE_LOGGING_AND_PROFILING
- isolate_->producer_heap_profile()->RecordJSObjectAllocation(result);
-#endif
return result;
}
@@ -3456,9 +3512,6 @@
JSObject::cast(clone)->set_properties(FixedArray::cast(prop));
}
// Return the new clone.
-#ifdef ENABLE_LOGGING_AND_PROFILING
- isolate_->producer_heap_profile()->RecordJSObjectAllocation(clone);
-#endif
return clone;
}
@@ -3873,6 +3926,62 @@
}
+MaybeObject* Heap::AllocateEmptyFixedDoubleArray() {
+ int size = FixedDoubleArray::SizeFor(0);
+ Object* result;
+ { MaybeObject* maybe_result =
+ AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ // Initialize the object.
+ reinterpret_cast<FixedDoubleArray*>(result)->set_map(
+ fixed_double_array_map());
+ reinterpret_cast<FixedDoubleArray*>(result)->set_length(0);
+ return result;
+}
+
+
+MaybeObject* Heap::AllocateUninitializedFixedDoubleArray(
+ int length,
+ PretenureFlag pretenure) {
+ if (length == 0) return empty_fixed_double_array();
+
+ Object* obj;
+ { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ }
+
+ reinterpret_cast<FixedDoubleArray*>(obj)->set_map(fixed_double_array_map());
+ FixedDoubleArray::cast(obj)->set_length(length);
+ return obj;
+}
+
+
+MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
+ PretenureFlag pretenure) {
+ if (length < 0 || length > FixedDoubleArray::kMaxLength) {
+ return Failure::OutOfMemoryException();
+ }
+
+ AllocationSpace space =
+ (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
+ int size = FixedDoubleArray::SizeFor(length);
+ if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) {
+ // Too big for new space.
+ space = LO_SPACE;
+ } else if (space == OLD_DATA_SPACE &&
+ size > MaxObjectSizeInPagedSpace()) {
+ // Too big for old data space.
+ space = LO_SPACE;
+ }
+
+ AllocationSpace retry_space =
+ (size <= MaxObjectSizeInPagedSpace()) ? OLD_DATA_SPACE : LO_SPACE;
+
+ return AllocateRaw(size, space, retry_space);
+}
+
+
MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
Object* result;
{ MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
@@ -3905,38 +4014,50 @@
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map(context_map());
+ context->set_map(function_context_map());
context->set_closure(function);
- context->set_fcontext(context);
- context->set_previous(NULL);
+ context->set_previous(function->context());
context->set_extension(NULL);
context->set_global(function->context()->global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(context->is_function_context());
- ASSERT(result->IsContext());
- return result;
+ return context;
}
-MaybeObject* Heap::AllocateWithContext(Context* previous,
- JSObject* extension,
- bool is_catch_context) {
+MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
+ Context* previous,
+ String* name,
+ Object* thrown_object) {
+ STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
Object* result;
+ { MaybeObject* maybe_result =
+ AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ Context* context = reinterpret_cast<Context*>(result);
+ context->set_map(catch_context_map());
+ context->set_closure(function);
+ context->set_previous(previous);
+ context->set_extension(name);
+ context->set_global(previous->global());
+ context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
+ return context;
+}
+
+
+MaybeObject* Heap::AllocateWithContext(JSFunction* function,
+ Context* previous,
+ JSObject* extension) {
+ Object* result;
{ MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map(is_catch_context ? catch_context_map() :
- context_map());
- context->set_closure(previous->closure());
- context->set_fcontext(previous->fcontext());
+ context->set_map(with_context_map());
+ context->set_closure(function);
context->set_previous(previous);
context->set_extension(extension);
context->set_global(previous->global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(!context->is_function_context());
- ASSERT(result->IsContext());
- return result;
+ return context;
}
@@ -4518,6 +4639,9 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
isolate_->debug()->Iterate(v);
+ if (isolate_->deoptimizer_data() != NULL) {
+ isolate_->deoptimizer_data()->Iterate(v);
+ }
#endif
v->Synchronize("debug");
isolate_->compilation_cache()->Iterate(v);
@@ -4542,7 +4666,7 @@
isolate_->global_handles()->IterateStrongRoots(v);
break;
case VISIT_ALL_IN_SCAVENGE:
- isolate_->global_handles()->IterateStrongAndDependentRoots(v);
+ isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
break;
case VISIT_ALL_IN_SWEEP_NEWSPACE:
case VISIT_ALL:
@@ -4958,11 +5082,6 @@
LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
LOG(isolate_, IntPtrTEvent("heap-available", Available()));
-#ifdef ENABLE_LOGGING_AND_PROFILING
- // This should be called only after initial objects have been created.
- isolate_->producer_heap_profile()->Setup();
-#endif
-
store_buffer()->Setup();
return true;
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698