| Index: runtime/vm/code_descriptors.h
|
| diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
|
| index d2faea285dbd8e28de593501d405c68887eff905..cde1cfce8e1ddb9ea3611d9eadb089f6e884bb20 100644
|
| --- a/runtime/vm/code_descriptors.h
|
| +++ b/runtime/vm/code_descriptors.h
|
| @@ -10,6 +10,7 @@
|
| #include "vm/globals.h"
|
| #include "vm/growable_array.h"
|
| #include "vm/object.h"
|
| +#include "vm/log.h"
|
|
|
| namespace dart {
|
|
|
| @@ -139,9 +140,20 @@ class ExceptionHandlerList : public ZoneAllocated {
|
| };
|
|
|
|
|
| +// A CodeSourceMap maps from pc offsets to a stack of inlined functions and
|
| +// their positions. This is encoded as a little bytecode that pushes and pops
|
| +// functions and changes the top function's position as the PC advances.
|
| +// Decoding happens by running this bytecode until we reach the desired PC.
|
| +//
|
| +// The implementation keeps track of two sets of state: one written to the byte
|
| +// stream and one that is buffered. On the JIT, this buffering effectively gives
|
| +// us a peephole optimization that merges adjacent advance PC bytecodes. On AOT,
|
| +// this allows to skip encoding our position until we reach a PC where we might
|
| +// throw.
|
| class CodeSourceMapBuilder : public ZoneAllocated {
|
| public:
|
| 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);
|
| @@ -159,47 +171,67 @@ class CodeSourceMapBuilder : public ZoneAllocated {
|
| void StartInliningInterval(int32_t pc_offset, intptr_t inline_id);
|
| void BeginCodeSourceRange(int32_t pc_offset);
|
| void EndCodeSourceRange(int32_t pc_offset, TokenPosition pos);
|
| + void NoteDescriptor(RawPcDescriptors::Kind kind,
|
| + int32_t pc_offset,
|
| + TokenPosition pos);
|
|
|
| RawArray* InliningIdToFunction();
|
| RawCodeSourceMap* Finalize();
|
|
|
| private:
|
| - void EmitPosition(TokenPosition pos) {
|
| - FlushPeephole();
|
| + void BufferChangePosition(TokenPosition pos) {
|
| + buffered_token_pos_stack_.Last() = pos;
|
| + }
|
| + void WriteChangePosition(TokenPosition pos) {
|
| stream_.Write<uint8_t>(kChangePosition);
|
| stream_.Write<int32_t>(static_cast<int32_t>(pos.value()));
|
| + written_token_pos_stack_.Last() = pos;
|
| }
|
| - void EmitAdvancePC(int32_t distance) { advance_pc_peephole_ += distance; }
|
| - void FlushPeephole() {
|
| - if (advance_pc_peephole_ != 0) {
|
| - stream_.Write<uint8_t>(kAdvancePC);
|
| - stream_.Write<int32_t>(advance_pc_peephole_);
|
| - advance_pc_peephole_ = 0;
|
| - }
|
| + void BufferAdvancePC(int32_t distance) { buffered_pc_offset_ += distance; }
|
| + void WriteAdvancePC(int32_t distance) {
|
| + stream_.Write<uint8_t>(kAdvancePC);
|
| + stream_.Write<int32_t>(distance);
|
| + written_pc_offset_ += distance;
|
| + }
|
| + void BufferPush(intptr_t inline_id) {
|
| + buffered_inline_id_stack_.Add(inline_id);
|
| + buffered_token_pos_stack_.Add(kInitialPosition);
|
| }
|
| - void EmitPush(intptr_t inline_id) {
|
| - FlushPeephole();
|
| + void WritePush(intptr_t inline_id) {
|
| stream_.Write<uint8_t>(kPushFunction);
|
| stream_.Write<int32_t>(inline_id);
|
| + written_inline_id_stack_.Add(inline_id);
|
| + written_token_pos_stack_.Add(kInitialPosition);
|
| }
|
| - void EmitPop() {
|
| - FlushPeephole();
|
| + void BufferPop() {
|
| + buffered_inline_id_stack_.RemoveLast();
|
| + buffered_token_pos_stack_.RemoveLast();
|
| + }
|
| + void WritePop() {
|
| stream_.Write<uint8_t>(kPopFunction);
|
| + written_inline_id_stack_.RemoveLast();
|
| + written_token_pos_stack_.RemoveLast();
|
| }
|
|
|
| - bool IsOnStack(intptr_t inline_id) {
|
| - for (intptr_t i = 0; i < inline_id_stack_.length(); i++) {
|
| - if (inline_id_stack_[i] == inline_id) {
|
| - return true;
|
| - }
|
| + void FlushBuffer();
|
| + void FlushBufferStack();
|
| + void FlushBufferPosition();
|
| + void FlushBufferPC();
|
| +
|
| + bool IsOnBufferedStack(intptr_t inline_id) {
|
| + for (intptr_t i = 0; i < buffered_inline_id_stack_.length(); i++) {
|
| + if (buffered_inline_id_stack_[i] == inline_id) return true;
|
| }
|
| return false;
|
| }
|
|
|
| - intptr_t pc_offset_;
|
| - intptr_t advance_pc_peephole_;
|
| - GrowableArray<intptr_t> inline_id_stack_;
|
| - GrowableArray<TokenPosition> token_pos_stack_;
|
| + intptr_t buffered_pc_offset_;
|
| + GrowableArray<intptr_t> buffered_inline_id_stack_;
|
| + GrowableArray<TokenPosition> buffered_token_pos_stack_;
|
| +
|
| + intptr_t written_pc_offset_;
|
| + GrowableArray<intptr_t> written_inline_id_stack_;
|
| + GrowableArray<TokenPosition> written_token_pos_stack_;
|
|
|
| const GrowableArray<intptr_t>& caller_inline_id_;
|
| const GrowableArray<TokenPosition>& inline_id_to_token_pos_;
|
| @@ -208,6 +240,8 @@ class CodeSourceMapBuilder : public ZoneAllocated {
|
| uint8_t* buffer_;
|
| WriteStream stream_;
|
|
|
| + const bool stack_traces_only_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder);
|
| };
|
|
|
|
|