Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 155e404d7b46b62d78eb9cd51e3e12617b6432d1..9e253611ef055be4c52496a90b261f06f9d5ea0b 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -625,6 +625,15 @@ class CaptureStackTraceHelper { |
Handle<StackFrameInfo> NewStackFrameObject( |
const FrameSummary::JavaScriptFrameSummary& summ) { |
+ int code_offset = summ.code_offset(); |
+ Handle<ByteArray> source_position_table( |
+ summ.abstract_code()->source_position_table(), isolate_); |
+ Handle<UnseededNumberDictionary> cache = GetCache(source_position_table); |
+ int entry = cache->FindEntry(code_offset); |
+ if (entry != UnseededNumberDictionary::kNotFound) { |
+ return handle(StackFrameInfo::cast(cache->ValueAt(entry)), isolate_); |
Yang
2017/04/04 19:47:06
You would check here whether the cached StackFrame
kozy
2017/04/04 20:48:24
It eliminates almost all performance benefits:
con
Yang
2017/04/04 21:15:18
Can we land this without performance improvements
kozy
2017/04/04 23:08:12
Yes, first + third sound good to me. I'll try to i
|
+ } |
+ |
Handle<StackFrameInfo> frame = factory()->NewStackFrameInfo(); |
Handle<Script> script = Handle<Script>::cast(summ.script()); |
if (options_ & StackTrace::kLineNumber) { |
@@ -657,6 +666,11 @@ class CaptureStackTraceHelper { |
if (options_ & StackTrace::kIsConstructor) { |
frame->set_is_constructor(summ.is_constructor()); |
} |
+ auto new_cache = |
+ UnseededNumberDictionary::AtNumberPut(cache, code_offset, frame); |
+ if (*new_cache != *cache) { |
+ PutCache(source_position_table, cache); |
+ } |
return frame; |
} |
@@ -691,6 +705,33 @@ class CaptureStackTraceHelper { |
private: |
inline Factory* factory() { return isolate_->factory(); } |
+ Handle<UnseededNumberDictionary> GetCache( |
+ Handle<ByteArray> source_position_table) { |
+ Handle<WeakHashTable> table_to_cache(isolate_->heap()->stack_frame_cache()); |
+ Object* maybe_cache = table_to_cache->Lookup(source_position_table); |
+ if (maybe_cache->IsUnseededNumberDictionary()) { |
+ return handle(UnseededNumberDictionary::cast(maybe_cache)); |
+ } |
+ Handle<UnseededNumberDictionary> cache = |
+ UnseededNumberDictionary::New(isolate_, 1); |
+ auto new_table_to_cache = |
+ WeakHashTable::Put(table_to_cache, source_position_table, cache); |
+ if (*new_table_to_cache != *table_to_cache) { |
+ isolate_->heap()->SetStackFrameCache(*new_table_to_cache); |
+ } |
+ return cache; |
+ } |
+ |
+ void PutCache(Handle<ByteArray> source_position_table, |
+ Handle<UnseededNumberDictionary> cache) { |
+ Handle<WeakHashTable> table_to_cache(isolate_->heap()->stack_frame_cache()); |
+ auto new_table_to_cache = |
+ WeakHashTable::Put(table_to_cache, source_position_table, cache); |
+ if (*new_table_to_cache != *table_to_cache) { |
+ isolate_->heap()->SetStackFrameCache(*new_table_to_cache); |
+ } |
+ } |
+ |
Isolate* isolate_; |
StackTrace::StackTraceOptions options_; |
}; |