Reviewers: Toon Verwaest,
Description:
Preprocess structured stack trace on GC to get rid of code reference.
[email protected]
BUG=v8:2340
LOG=N
Please review this at https://codereview.chromium.org/1103843002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+75, -5 lines):
M src/factory.h
M src/heap/heap.h
M src/heap/heap.cc
M src/isolate.cc
M src/messages.js
M src/objects.h
M src/objects.cc
M src/objects-inl.h
M test/cctest/test-heap.cc
Index: src/factory.h
diff --git a/src/factory.h b/src/factory.h
index
72991d9bf0ca7ef405c170a6f19029a5a2f3305f..0ab312b2b7e1b283a307a9070823725fcb888565
100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -644,6 +644,10 @@ class Factory final {
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_);
}
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index
985d1f678862d87aa0c283aade75e79b3c8b0936..e276f570c36710470b577be1e65d02bcf64c3541
100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -408,6 +408,8 @@ void Heap::GarbageCollectionPrologue() {
#endif
}
+ PreprocessStackTraces();
+
// Reset GC statistics.
promoted_objects_size_ = 0;
previous_semi_space_copied_object_size_ = semi_space_copied_object_size_;
@@ -706,6 +708,26 @@ void Heap::GarbageCollectionEpilogue() {
}
+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 i = 1; i < elements->length(); i += 4) {
+ Code* code = Code::cast(elements->get(i + 2));
+ int offset = Smi::cast(elements->get(i + 3))->value();
+ Address pc = code->address() + offset;
+ int pos = code->SourcePosition(pc);
+ elements->set(i + 2, Smi::FromInt(pos));
+ }
+ array->Clear(i);
+ }
+ array->Compact();
+}
+
+
void Heap::HandleGCRequest() {
if (incremental_marking()->request_type() ==
IncrementalMarking::COMPLETE_MARKING) {
@@ -3082,6 +3104,8 @@ void Heap::CreateInitialObjects() {
cell->set_value(Smi::FromInt(1));
set_array_protector(*cell);
+ set_weak_stack_trace_list(Smi::FromInt(0));
+
set_allocation_sites_scratchpad(
*factory->NewFixedArray(kAllocationSiteScratchpadSize, TENURED));
InitializeAllocationSitesScratchpad();
@@ -3118,6 +3142,7 @@ bool
Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
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)
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index
dcf7bdea0ac812972304bd382d52b0a1f4c5eff2..887d9c0cebdb8fdc120f2d6bf6b8aa6080576c5c
100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -186,7 +186,8 @@ namespace internal {
V(FixedArray, detached_contexts,
DetachedContexts) \
V(ArrayList, retained_maps,
RetainedMaps) \
V(WeakHashTable, weak_object_to_code_table,
WeakObjectToCodeTable) \
- V(PropertyCell, array_protector, ArrayProtector)
+ V(PropertyCell, array_protector,
ArrayProtector) \
+ V(Object, weak_stack_trace_list, WeakStackTraceList)
// Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V)
\
@@ -1742,6 +1743,8 @@ class Heap {
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.
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index
5427a8c319d59369dd8f6e5fbde3aea5789e1d43..90559b341bf8112b6500dbe4093e9225c5a57494
100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -409,6 +409,10 @@ Handle<Object>
Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object,
elements->set(0, Smi::FromInt(sloppy_frames));
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;
}
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index
0e48ae60bd1fa360278ea16fa78a142b37fb6309..c600eec4ae726b6cba7aba8a6f9b9b65b85bed23
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -1016,7 +1016,7 @@ function GetStackFrames(raw_stack) {
var fun = raw_stack[i + 1];
var code = raw_stack[i + 2];
var pc = raw_stack[i + 3];
- var pos = %FunctionGetPositionForOffset(code, pc);
+ var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code,
pc);
sloppy_frames--;
frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
}
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
2e77f92927613732b2a1579824f27319330ee345..b1df7fc330523c788a437bcb5f794d5592e7dd13
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2356,7 +2356,7 @@ bool WeakFixedArray::IsEmptySlot(int index) const {
}
-void WeakFixedArray::clear(int index) {
+void WeakFixedArray::Clear(int index) {
FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
}
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
f3733295c4dc1baf9d27330aa5a4200a3a3b999b..93dd606c10634879c78dc67f68fb9f92a7cbb281
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8320,7 +8320,7 @@ void WeakFixedArray::Remove(Handle<HeapObject> value)
{
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;
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
68db075981513de26558e03cc12017748c9d32f4..459975b5c0614d485499291c3ac72f162f250a28
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2628,8 +2628,10 @@ class WeakFixedArray : public FixedArray {
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)
@@ -2644,7 +2646,6 @@ class WeakFixedArray : public FixedArray {
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);
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index
8858a82d9adf7f838a0add8538918278d1ba7748..a156e97410c44187abdf4328ba3f29575b9d4714
100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -5369,3 +5369,36 @@ TEST(Regress472513) {
TestRightTrimFixedTypedArray(i::kExternalUint16Array, 8 - 1, 3);
TestRightTrimFixedTypedArray(i::kExternalUint32Array, 4, 3);
}
+
+
+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());
+ }
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.