isolate()->heap()->set_string_table(*table);
}
- inline void set_weak_stack_trace_list(Handle<WeakFixedArray> list) {
- isolate()->heap()->set_weak_stack_trace_list(*list);
- }
-
Handle<String> hidden_string() {
return Handle<String>(&isolate()->heap()->hidden_string_);
}
}
-void Heap::PreprocessStackTraces() {
- if (!weak_stack_trace_list()->IsWeakFixedArray()) return;
- WeakFixedArray* array = WeakFixedArray::cast(weak_stack_trace_list());
- int length = array->Length();
- for (int i = 0; i < length; i++) {
- if (array->IsEmptySlot(i)) continue;
- FixedArray* elements = FixedArray::cast(array->Get(i));
- for (int j = 1; j < elements->length(); j += 4) {
- Code* code = Code::cast(elements->get(j + 2));
- int offset = Smi::cast(elements->get(j + 3))->value();
- Address pc = code->address() + offset;
- int pos = code->SourcePosition(pc);
- elements->set(j + 2, Smi::FromInt(pos));
- }
- array->Clear(i);
- }
- array->Compact();
-}
-
-
void Heap::HandleGCRequest() {
if (incremental_marking()->request_type() ==
IncrementalMarking::COMPLETE_MARKING) {
isolate_->counters()->objs_since_last_full()->Set(0);
incremental_marking()->Epilogue();
-
- PreprocessStackTraces();
}
cell->set_value(Smi::FromInt(Isolate::kArrayProtectorValid));
set_array_protector(*cell);
- set_weak_stack_trace_list(Smi::FromInt(0));
-
set_allocation_sites_scratchpad(
*factory->NewFixedArray(kAllocationSiteScratchpadSize, TENURED));
InitializeAllocationSitesScratchpad();
case kDetachedContextsRootIndex:
case kWeakObjectToCodeTableRootIndex:
case kRetainedMapsRootIndex:
- case kWeakStackTraceListRootIndex:
// Smi values
#define SMI_ENTRY(type, name, Name) case k##Name##RootIndex:
SMI_ROOT_LIST(SMI_ENTRY)
V(FixedArray, detached_contexts, DetachedContexts) \
V(ArrayList, retained_maps, RetainedMaps) \
V(WeakHashTable, weak_object_to_code_table, WeakObjectToCodeTable) \
- V(PropertyCell, array_protector, ArrayProtector) \
- V(Object, weak_stack_trace_list, WeakStackTraceList)
+ V(PropertyCell, array_protector, ArrayProtector)
// Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V) \
void GarbageCollectionPrologue();
void GarbageCollectionEpilogue();
- void PreprocessStackTraces();
-
// Pretenuring decisions are made based on feedback collected during new
// space evacuation. Note that between feedback collection and calling this
// method object in old space must not move.
}
}
elements->set(0, Smi::FromInt(sloppy_frames));
- elements->Shrink(cursor);
Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
result->set_length(Smi::FromInt(cursor));
- // Queue this structured stack trace for preprocessing on GC.
- Handle<WeakFixedArray> new_weak_list =
- WeakFixedArray::Add(factory()->weak_stack_trace_list(), elements);
- factory()->set_weak_stack_trace_list(new_weak_list);
return result;
}
var fun = raw_stack[i + 1];
var code = raw_stack[i + 2];
var pc = raw_stack[i + 3];
- var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
+ var pos = %FunctionGetPositionForOffset(code, pc);
sloppy_frames--;
frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
}
}
-void WeakFixedArray::Clear(int index) {
+void WeakFixedArray::clear(int index) {
FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
}
int first_index = last_used_index();
for (int i = first_index;;) {
if (Get(i) == *value) {
- Clear(i);
+ clear(i);
// Users of WeakFixedArray should make sure that there are no duplicates,
// they can use Add(..., kAddIfNotFound) if necessary.
return true;
void Compact();
inline Object* Get(int index) const;
- inline void Clear(int index);
inline int Length() const;
- inline bool IsEmptySlot(int index) const;
static Object* Empty() { return Smi::FromInt(0); }
DECLARE_CAST(WeakFixedArray)
static void Set(Handle<WeakFixedArray> array, int index,
Handle<HeapObject> value);
inline void clear(int index);
+ inline bool IsEmptySlot(int index) const;
inline int last_used_index() const;
inline void set_last_used_index(int index);
array->Compact();
WeakFixedArray::Add(array, number);
}
-
-
-TEST(PreprocessStackTrace) {
- // Do not automatically trigger early GC.
- FLAG_gc_interval = -1;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- v8::TryCatch try_catch;
- CompileRun("throw new Error();");
- CHECK(try_catch.HasCaught());
- Isolate* isolate = CcTest::i_isolate();
- Handle<Object> exception = v8::Utils::OpenHandle(*try_catch.Exception());
- Handle<Name> key = isolate->factory()->stack_trace_symbol();
- Handle<Object> stack_trace =
- JSObject::GetProperty(exception, key).ToHandleChecked();
- Handle<Object> code =
- Object::GetElement(isolate, stack_trace, 3).ToHandleChecked();
- CHECK(code->IsCode());
-
- isolate->heap()->CollectAllAvailableGarbage("stack trace preprocessing");
-
- Handle<Object> pos =
- Object::GetElement(isolate, stack_trace, 3).ToHandleChecked();
- CHECK(pos->IsSmi());
-
- Handle<JSArray> stack_trace_array = Handle<JSArray>::cast(stack_trace);
- int array_length = Smi::cast(stack_trace_array->length())->value();
- for (int i = 0; i < array_length; i++) {
- Handle<Object> element =
- Object::GetElement(isolate, stack_trace, i).ToHandleChecked();
- CHECK(!element->IsCode());
- }
-}