Commit 92537552 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Rip out infrastructure for deferred stack trace formatting.

R=mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/19971002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15816 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5aa717a0
......@@ -712,19 +712,6 @@ void ExternalStringTable::ShrinkNewStrings(int position) {
}
void ErrorObjectList::Add(JSObject* object) {
list_.Add(object);
}
void ErrorObjectList::Iterate(ObjectVisitor* v) {
if (!list_.is_empty()) {
Object** start = &list_[0];
v->VisitPointers(start, start + list_.length());
}
}
void Heap::ClearInstanceofCache() {
set_instanceof_cache_function(the_hole_value());
}
......
......@@ -583,8 +583,6 @@ void Heap::GarbageCollectionEpilogue() {
#ifdef ENABLE_DEBUGGER_SUPPORT
isolate_->debug()->AfterGarbageCollection();
#endif // ENABLE_DEBUGGER_SUPPORT
error_object_list_.DeferredFormatStackTrace(isolate());
}
......@@ -1428,8 +1426,6 @@ void Heap::Scavenge() {
UpdateNewSpaceReferencesInExternalStringTable(
&UpdateNewSpaceReferenceInExternalStringTableEntry);
error_object_list_.UpdateReferencesInNewSpace(this);
promotion_queue_.Destroy();
if (!FLAG_watch_ic_patching) {
......@@ -6575,7 +6571,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);
}
......@@ -6975,8 +6970,6 @@ void Heap::TearDown() {
external_string_table_.TearDown();
error_object_list_.TearDown();
new_space_.TearDown();
if (old_pointer_space_ != NULL) {
......@@ -7929,120 +7922,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;
......
......@@ -475,41 +475,6 @@ class ExternalStringTable {
};
// The stack property of an error object is implemented as a getter that
// formats the attached raw stack trace into a string. This raw stack trace
// keeps code and function objects alive until the getter is called the first
// time. To release those objects, we call the getter after each GC for
// newly tenured error objects that are kept in a list.
class ErrorObjectList {
public:
inline void Add(JSObject* object);
inline void Iterate(ObjectVisitor* v);
void TearDown();
void RemoveUnmarked(Heap* heap);
void DeferredFormatStackTrace(Isolate* isolate);
void UpdateReferences();
void UpdateReferencesInNewSpace(Heap* heap);
private:
static const int kBudgetPerGC = 16;
ErrorObjectList() : nested_(false) { }
friend class Heap;
List<Object*> list_;
bool nested_;
DISALLOW_COPY_AND_ASSIGN(ErrorObjectList);
};
enum ArrayStorageAllocationMode {
DONT_INITIALIZE_ARRAY_ELEMENTS,
INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
......@@ -1798,10 +1763,6 @@ class Heap {
return &external_string_table_;
}
ErrorObjectList* error_object_list() {
return &error_object_list_;
}
// Returns the current sweep generation.
int sweep_generation() {
return sweep_generation_;
......@@ -2406,8 +2367,6 @@ class Heap {
ExternalStringTable external_string_table_;
ErrorObjectList error_object_list_;
VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
MemoryChunk* chunks_queued_for_free_;
......
......@@ -2396,7 +2396,6 @@ void MarkCompactCollector::AfterMarking() {
string_table->ElementsRemoved(v.PointersRemoved());
heap()->external_string_table_.Iterate(&v);
heap()->external_string_table_.CleanUp();
heap()->error_object_list_.RemoveUnmarked(heap());
// Process the weak references.
MarkCompactWeakObjectRetainer mark_compact_object_retainer;
......@@ -3463,9 +3462,6 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
heap_->UpdateReferencesInExternalStringTable(
&UpdateReferenceInExternalStringTableEntry);
// Update pointers in the new error object list.
heap_->error_object_list()->UpdateReferences();
if (!FLAG_watch_ic_patching) {
// Update JSFunction pointers from the runtime profiler.
heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment