Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index db8086fd84282e684a38a136c5a06d12d8288529..b09e02210f12697689e05fe371f0c72ec73b2e53 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -583,8 +583,6 @@ void Heap::GarbageCollectionEpilogue() { |
#ifdef ENABLE_DEBUGGER_SUPPORT |
isolate_->debug()->AfterGarbageCollection(); |
#endif // ENABLE_DEBUGGER_SUPPORT |
- |
- error_object_list_.DeferredFormatStackTrace(isolate()); |
} |
@@ -705,6 +703,16 @@ bool Heap::CollectGarbage(AllocationSpace space, |
} |
+int Heap::NotifyContextDisposed() { |
+ if (FLAG_parallel_recompilation) { |
+ // Flush the queued recompilation tasks. |
+ isolate()->optimizing_compiler_thread()->Flush(); |
+ } |
+ flush_monomorphic_ics_ = true; |
+ return ++contexts_disposed_; |
+} |
+ |
+ |
void Heap::PerformScavenge() { |
GCTracer tracer(this, NULL, NULL); |
if (incremental_marking()->IsStopped()) { |
@@ -922,6 +930,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, |
{ |
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
VMState<EXTERNAL> state(isolate_); |
+ HandleScope handle_scope(isolate_); |
CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags); |
} |
@@ -1027,6 +1036,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, |
{ |
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
VMState<EXTERNAL> state(isolate_); |
+ HandleScope handle_scope(isolate_); |
CallGCEpilogueCallbacks(gc_type); |
} |
@@ -1428,8 +1438,6 @@ void Heap::Scavenge() { |
UpdateNewSpaceReferencesInExternalStringTable( |
&UpdateNewSpaceReferenceInExternalStringTableEntry); |
- error_object_list_.UpdateReferencesInNewSpace(this); |
- |
promotion_queue_.Destroy(); |
if (!FLAG_watch_ic_patching) { |
@@ -3220,6 +3228,9 @@ bool Heap::CreateInitialObjects() { |
} |
set_observed_symbol(Symbol::cast(obj)); |
+ set_i18n_template_one(the_hole_value()); |
+ set_i18n_template_two(the_hole_value()); |
+ |
// Handling of script id generation is in Factory::NewScript. |
set_last_script_id(Smi::FromInt(v8::Script::kNoScriptId)); |
@@ -5358,25 +5369,16 @@ MaybeObject* Heap::AllocateRawOneByteString(int length, |
if (length < 0 || length > SeqOneByteString::kMaxLength) { |
return Failure::OutOfMemoryException(0xb); |
} |
- |
int size = SeqOneByteString::SizeFor(length); |
ASSERT(size <= SeqOneByteString::kMaxSize); |
- |
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
AllocationSpace retry_space = OLD_DATA_SPACE; |
- if (space == NEW_SPACE) { |
- if (size > kMaxObjectSizeInNewSpace) { |
- // Allocate in large object space, retry space will be ignored. |
- space = LO_SPACE; |
- } else if (size > Page::kMaxNonCodeHeapObjectSize) { |
- // Allocate in new space, retry in large object space. |
- retry_space = LO_SPACE; |
- } |
- } else if (space == OLD_DATA_SPACE && |
- size > Page::kMaxNonCodeHeapObjectSize) { |
+ if (size > Page::kMaxNonCodeHeapObjectSize) { |
+ // Allocate in large object space, retry space will be ignored. |
space = LO_SPACE; |
} |
+ |
Object* result; |
{ MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
if (!maybe_result->ToObject(&result)) return maybe_result; |
@@ -5402,18 +5404,11 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length, |
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
AllocationSpace retry_space = OLD_DATA_SPACE; |
- if (space == NEW_SPACE) { |
- if (size > kMaxObjectSizeInNewSpace) { |
- // Allocate in large object space, retry space will be ignored. |
- space = LO_SPACE; |
- } else if (size > Page::kMaxNonCodeHeapObjectSize) { |
- // Allocate in new space, retry in large object space. |
- retry_space = LO_SPACE; |
- } |
- } else if (space == OLD_DATA_SPACE && |
- size > Page::kMaxNonCodeHeapObjectSize) { |
+ if (size > Page::kMaxNonCodeHeapObjectSize) { |
+ // Allocate in large object space, retry space will be ignored. |
space = LO_SPACE; |
} |
+ |
Object* result; |
{ MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
if (!maybe_result->ToObject(&result)) return maybe_result; |
@@ -5487,7 +5482,7 @@ MaybeObject* Heap::AllocateRawFixedArray(int length) { |
if (always_allocate()) return AllocateFixedArray(length, TENURED); |
// Allocate the raw data for a fixed array. |
int size = FixedArray::SizeFor(length); |
- return size <= kMaxObjectSizeInNewSpace |
+ return size <= Page::kMaxNonCodeHeapObjectSize |
? new_space_.AllocateRaw(size) |
: lo_space_->AllocateRaw(size, NOT_EXECUTABLE); |
} |
@@ -5558,22 +5553,16 @@ MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { |
if (length < 0 || length > FixedArray::kMaxLength) { |
return Failure::OutOfMemoryException(0xe); |
} |
- |
+ int size = FixedArray::SizeFor(length); |
AllocationSpace space = |
(pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
- int size = FixedArray::SizeFor(length); |
- if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
- // Too big for new space. |
- space = LO_SPACE; |
- } else if (space == OLD_POINTER_SPACE && |
- size > Page::kMaxNonCodeHeapObjectSize) { |
- // Too big for old pointer space. |
+ AllocationSpace retry_space = OLD_POINTER_SPACE; |
+ |
+ if (size > Page::kMaxNonCodeHeapObjectSize) { |
+ // Allocate in large object space, retry space will be ignored. |
space = LO_SPACE; |
} |
- AllocationSpace retry_space = |
- (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_POINTER_SPACE : LO_SPACE; |
- |
return AllocateRaw(size, space, retry_space); |
} |
@@ -5691,27 +5680,19 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, |
if (length < 0 || length > FixedDoubleArray::kMaxLength) { |
return Failure::OutOfMemoryException(0xf); |
} |
- |
- AllocationSpace space = |
- (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
int size = FixedDoubleArray::SizeFor(length); |
+ AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
+ AllocationSpace retry_space = OLD_DATA_SPACE; |
#ifndef V8_HOST_ARCH_64_BIT |
size += kPointerSize; |
#endif |
- if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
- // Too big for new space. |
- space = LO_SPACE; |
- } else if (space == OLD_DATA_SPACE && |
- size > Page::kMaxNonCodeHeapObjectSize) { |
- // Too big for old data space. |
+ if (size > Page::kMaxNonCodeHeapObjectSize) { |
+ // Allocate in large object space, retry space will be ignored. |
space = LO_SPACE; |
} |
- AllocationSpace retry_space = |
- (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_DATA_SPACE : LO_SPACE; |
- |
HeapObject* object; |
{ MaybeObject* maybe_object = AllocateRaw(size, space, retry_space); |
if (!maybe_object->To<HeapObject>(&object)) return maybe_object; |
@@ -6580,7 +6561,6 @@ void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { |
mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
// Scavenge collections have special processing for this. |
external_string_table_.Iterate(v); |
- error_object_list_.Iterate(v); |
} |
v->Synchronize(VisitorSynchronization::kExternalStringsTable); |
} |
@@ -6980,8 +6960,6 @@ void Heap::TearDown() { |
external_string_table_.TearDown(); |
- error_object_list_.TearDown(); |
- |
new_space_.TearDown(); |
if (old_pointer_space_ != NULL) { |
@@ -7934,120 +7912,6 @@ void ExternalStringTable::TearDown() { |
} |
-// Update all references. |
-void ErrorObjectList::UpdateReferences() { |
- for (int i = 0; i < list_.length(); i++) { |
- HeapObject* object = HeapObject::cast(list_[i]); |
- MapWord first_word = object->map_word(); |
- if (first_word.IsForwardingAddress()) { |
- list_[i] = first_word.ToForwardingAddress(); |
- } |
- } |
-} |
- |
- |
-// Unforwarded objects in new space are dead and removed from the list. |
-void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) { |
- if (list_.is_empty()) return; |
- if (!nested_) { |
- int write_index = 0; |
- for (int i = 0; i < list_.length(); i++) { |
- MapWord first_word = HeapObject::cast(list_[i])->map_word(); |
- if (first_word.IsForwardingAddress()) { |
- list_[write_index++] = first_word.ToForwardingAddress(); |
- } |
- } |
- list_.Rewind(write_index); |
- } else { |
- // If a GC is triggered during DeferredFormatStackTrace, we do not move |
- // objects in the list, just remove dead ones, as to not confuse the |
- // loop in DeferredFormatStackTrace. |
- for (int i = 0; i < list_.length(); i++) { |
- MapWord first_word = HeapObject::cast(list_[i])->map_word(); |
- list_[i] = first_word.IsForwardingAddress() |
- ? first_word.ToForwardingAddress() |
- : heap->the_hole_value(); |
- } |
- } |
-} |
- |
- |
-void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) { |
- // If formatting the stack trace causes a GC, this method will be |
- // recursively called. In that case, skip the recursive call, since |
- // the loop modifies the list while iterating over it. |
- if (nested_ || list_.is_empty() || isolate->has_pending_exception()) return; |
- nested_ = true; |
- HandleScope scope(isolate); |
- Handle<String> stack_key = isolate->factory()->stack_string(); |
- int write_index = 0; |
- int budget = kBudgetPerGC; |
- for (int i = 0; i < list_.length(); i++) { |
- Object* object = list_[i]; |
- JSFunction* getter_fun; |
- |
- { DisallowHeapAllocation no_gc; |
- // Skip possible holes in the list. |
- if (object->IsTheHole()) continue; |
- if (isolate->heap()->InNewSpace(object) || budget == 0) { |
- list_[write_index++] = object; |
- continue; |
- } |
- |
- // Check whether the stack property is backed by the original getter. |
- LookupResult lookup(isolate); |
- JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup); |
- if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue; |
- Object* callback = lookup.GetCallbackObject(); |
- if (!callback->IsAccessorPair()) continue; |
- Object* getter_obj = AccessorPair::cast(callback)->getter(); |
- if (!getter_obj->IsJSFunction()) continue; |
- getter_fun = JSFunction::cast(getter_obj); |
- String* key = isolate->heap()->hidden_stack_trace_string(); |
- Object* value = getter_fun->GetHiddenProperty(key); |
- if (key != value) continue; |
- } |
- |
- budget--; |
- HandleScope scope(isolate); |
- bool has_exception = false; |
-#ifdef DEBUG |
- Handle<Map> map(HeapObject::cast(object)->map(), isolate); |
-#endif |
- Handle<Object> object_handle(object, isolate); |
- Handle<Object> getter_handle(getter_fun, isolate); |
- Execution::Call(getter_handle, object_handle, 0, NULL, &has_exception); |
- ASSERT(*map == HeapObject::cast(*object_handle)->map()); |
- if (has_exception) { |
- // Hit an exception (most likely a stack overflow). |
- // Wrap up this pass and retry after another GC. |
- isolate->clear_pending_exception(); |
- // We use the handle since calling the getter might have caused a GC. |
- list_[write_index++] = *object_handle; |
- budget = 0; |
- } |
- } |
- list_.Rewind(write_index); |
- list_.Trim(); |
- nested_ = false; |
-} |
- |
- |
-void ErrorObjectList::RemoveUnmarked(Heap* heap) { |
- for (int i = 0; i < list_.length(); i++) { |
- HeapObject* object = HeapObject::cast(list_[i]); |
- if (!Marking::MarkBitFrom(object).Get()) { |
- list_[i] = heap->the_hole_value(); |
- } |
- } |
-} |
- |
- |
-void ErrorObjectList::TearDown() { |
- list_.Free(); |
-} |
- |
- |
void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { |
chunk->set_next_chunk(chunks_queued_for_free_); |
chunks_queued_for_free_ = chunk; |