Index: runtime/vm/code_descriptors.cc |
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc |
index 0631bfee3f588446607221bb43bd48133a093a26..7bccb7d2e3efc36dafaa4e52cc84c0c2fd4bf578 100644 |
--- a/runtime/vm/code_descriptors.cc |
+++ b/runtime/vm/code_descriptors.cc |
@@ -128,26 +128,86 @@ const TokenPosition CodeSourceMapBuilder::kInitialPosition = |
CodeSourceMapBuilder::CodeSourceMapBuilder( |
+ bool stack_traces_only, |
const GrowableArray<intptr_t>& caller_inline_id, |
const GrowableArray<TokenPosition>& inline_id_to_token_pos, |
const GrowableArray<const Function*>& inline_id_to_function) |
- : pc_offset_(0), |
- advance_pc_peephole_(0), |
- inline_id_stack_(), |
- token_pos_stack_(), |
+ : buffered_pc_offset_(0), |
+ buffered_inline_id_stack_(), |
+ buffered_token_pos_stack_(), |
+ written_pc_offset_(0), |
+ written_inline_id_stack_(), |
+ written_token_pos_stack_(), |
caller_inline_id_(caller_inline_id), |
inline_id_to_token_pos_(inline_id_to_token_pos), |
inline_id_to_function_(inline_id_to_function), |
buffer_(NULL), |
- stream_(&buffer_, zone_allocator, 64) { |
- inline_id_stack_.Add(0); |
- token_pos_stack_.Add(TokenPosition::kDartCodePrologue); |
+ stream_(&buffer_, zone_allocator, 64), |
+ stack_traces_only_(stack_traces_only) { |
+ buffered_inline_id_stack_.Add(0); |
+ buffered_token_pos_stack_.Add(kInitialPosition); |
+ written_inline_id_stack_.Add(0); |
+ written_token_pos_stack_.Add(kInitialPosition); |
+} |
+ |
+ |
+void CodeSourceMapBuilder::FlushBuffer() { |
+ FlushBufferStack(); |
+ FlushBufferPosition(); |
+ FlushBufferPC(); |
+} |
+ |
+ |
+void CodeSourceMapBuilder::FlushBufferStack() { |
+ for (intptr_t i = buffered_inline_id_stack_.length() - 1; i >= 0; i--) { |
+ intptr_t buffered_id = buffered_inline_id_stack_[i]; |
+ if (i < written_inline_id_stack_.length()) { |
+ intptr_t written_id = written_inline_id_stack_[i]; |
+ if (buffered_id == written_id) { |
+ // i is the top-most position where the buffered and written stack |
+ // match. |
+ while (written_inline_id_stack_.length() > i + 1) { |
+ WritePop(); |
+ } |
+ for (intptr_t j = i + 1; j < buffered_inline_id_stack_.length(); j++) { |
+ TokenPosition buffered_pos = buffered_token_pos_stack_[j - 1]; |
+ TokenPosition written_pos = written_token_pos_stack_[j - 1]; |
+ if (buffered_pos != written_pos) { |
+ WriteChangePosition(buffered_pos); |
+ } |
+ WritePush(buffered_inline_id_stack_[j]); |
+ } |
+ return; |
+ } |
+ } |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+void CodeSourceMapBuilder::FlushBufferPosition() { |
+ ASSERT(buffered_token_pos_stack_.length() == |
+ written_token_pos_stack_.length()); |
+ |
+ intptr_t top = buffered_token_pos_stack_.length() - 1; |
+ TokenPosition buffered_pos = buffered_token_pos_stack_[top]; |
+ TokenPosition written_pos = written_token_pos_stack_[top]; |
+ if (buffered_pos != written_pos) { |
+ WriteChangePosition(buffered_pos); |
+ } |
+} |
+ |
+ |
+void CodeSourceMapBuilder::FlushBufferPC() { |
+ if (buffered_pc_offset_ != written_pc_offset_) { |
+ WriteAdvancePC(buffered_pc_offset_ - written_pc_offset_); |
+ } |
} |
void CodeSourceMapBuilder::StartInliningInterval(int32_t pc_offset, |
intptr_t inline_id) { |
- if (inline_id_stack_.Last() == inline_id) { |
+ if (buffered_inline_id_stack_.Last() == inline_id) { |
// No change in function stack. |
return; |
} |
@@ -156,18 +216,20 @@ void CodeSourceMapBuilder::StartInliningInterval(int32_t pc_offset, |
return; |
} |
+ if (!stack_traces_only_) { |
+ FlushBuffer(); |
+ } |
+ |
// Find a minimal set of pops and pushes to bring us to the new function |
// stack. |
// Pop to a common ancestor. |
intptr_t common_parent = inline_id; |
- while (!IsOnStack(common_parent)) { |
+ while (!IsOnBufferedStack(common_parent)) { |
common_parent = caller_inline_id_[common_parent]; |
} |
- while (inline_id_stack_.Last() != common_parent) { |
- EmitPop(); |
- inline_id_stack_.RemoveLast(); |
- token_pos_stack_.RemoveLast(); |
+ while (buffered_inline_id_stack_.Last() != common_parent) { |
+ BufferPop(); |
} |
// Push to the new top-of-stack function. |
@@ -178,23 +240,19 @@ void CodeSourceMapBuilder::StartInliningInterval(int32_t pc_offset, |
id = caller_inline_id_[id]; |
} |
for (intptr_t i = to_push.length() - 1; i >= 0; i--) { |
- intptr_t push_id = to_push[i]; |
+ intptr_t callee_id = to_push[i]; |
TokenPosition call_token; |
- if (push_id != 0) { |
+ if (callee_id != 0) { |
// TODO(rmacnak): Should make this array line up with the others. |
- call_token = inline_id_to_token_pos_[push_id - 1]; |
+ call_token = inline_id_to_token_pos_[callee_id - 1]; |
+ } else { |
+ UNREACHABLE(); |
} |
// Report caller as at the position of the call. |
- if (call_token != token_pos_stack_.Last()) { |
- EmitPosition(call_token); |
- token_pos_stack_[token_pos_stack_.length() - 1] = call_token; |
- } |
+ BufferChangePosition(call_token); |
- // Push the callee. |
- EmitPush(push_id); |
- inline_id_stack_.Add(push_id); |
- token_pos_stack_.Add(TokenPosition::kDartCodePrologue); |
+ BufferPush(callee_id); |
} |
} |
@@ -204,15 +262,30 @@ void CodeSourceMapBuilder::BeginCodeSourceRange(int32_t pc_offset) {} |
void CodeSourceMapBuilder::EndCodeSourceRange(int32_t pc_offset, |
TokenPosition pos) { |
- if (pc_offset == pc_offset_) { |
+ if (pc_offset == buffered_pc_offset_) { |
return; // Empty intermediate instruction. |
} |
- if (pos != token_pos_stack_.Last()) { |
- EmitPosition(pos); |
- token_pos_stack_[token_pos_stack_.length() - 1] = pos; |
+ if (pos != buffered_token_pos_stack_.Last()) { |
+ if (!stack_traces_only_) { |
+ FlushBuffer(); |
+ } |
+ BufferChangePosition(pos); |
+ } |
+ BufferAdvancePC(pc_offset - buffered_pc_offset_); |
+} |
+ |
+ |
+void CodeSourceMapBuilder::NoteDescriptor(RawPcDescriptors::Kind kind, |
+ int32_t pc_offset, |
+ TokenPosition pos) { |
+ const uint8_t kCanThrow = |
+ RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall | |
+ RawPcDescriptors::kRuntimeCall | RawPcDescriptors::kOther; |
+ if (stack_traces_only_ && ((kind & kCanThrow) != 0)) { |
+ BufferChangePosition(pos); |
+ BufferAdvancePC(pc_offset - buffered_pc_offset_); |
+ FlushBuffer(); |
} |
- EmitAdvancePC(pc_offset - pc_offset_); |
- pc_offset_ = pc_offset; |
} |
@@ -231,7 +304,9 @@ RawArray* CodeSourceMapBuilder::InliningIdToFunction() { |
RawCodeSourceMap* CodeSourceMapBuilder::Finalize() { |
- FlushPeephole(); |
+ if (!stack_traces_only_) { |
+ FlushBuffer(); |
+ } |
intptr_t length = stream_.bytes_written(); |
const CodeSourceMap& map = CodeSourceMap::Handle(CodeSourceMap::New(length)); |
NoSafepointScope no_safepoint; |