1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_DEX_QUICK_LAZY_DEBUG_FRAME_OPCODE_WRITER_H_
18 #define ART_COMPILER_DEX_QUICK_LAZY_DEBUG_FRAME_OPCODE_WRITER_H_
19 
20 #include "base/arena_allocator.h"
21 #include "base/arena_containers.h"
22 #include "dwarf/debug_frame_opcode_writer.h"
23 
24 namespace art {
25 struct LIR;
26 namespace dwarf {
27 
28 // When we are generating the CFI code, we do not know the instuction offsets,
29 // this class stores the LIR references and patches the instruction stream later.
30 class LazyDebugFrameOpCodeWriter FINAL
31     : public DebugFrameOpCodeWriter<ArenaAllocatorAdapter<uint8_t>> {
32   typedef DebugFrameOpCodeWriter<ArenaAllocatorAdapter<uint8_t>> Base;
33  public:
34   // This method is implicitely called the by opcode writers.
ImplicitlyAdvancePC()35   virtual void ImplicitlyAdvancePC() OVERRIDE {
36     DCHECK_EQ(patched_, false);
37     DCHECK_EQ(this->current_pc_, 0);
38     advances_.push_back({this->data()->size(), *last_lir_insn_});
39   }
40 
41   const ArenaVector<uint8_t>* Patch(size_t code_size);
42 
LazyDebugFrameOpCodeWriter(LIR ** last_lir_insn,bool enable_writes,ArenaAllocator * allocator)43   explicit LazyDebugFrameOpCodeWriter(LIR** last_lir_insn, bool enable_writes,
44                                       ArenaAllocator* allocator)
45     : Base(enable_writes, allocator->Adapter()),
46       last_lir_insn_(last_lir_insn),
47       advances_(allocator->Adapter()),
48       patched_(false) {
49   }
50 
51  private:
52   typedef struct {
53     size_t pos;
54     LIR* last_lir_insn;
55   } Advance;
56 
57   using Base::data;  // Hidden. Use Patch method instead.
58 
59   LIR** last_lir_insn_;
60   ArenaVector<Advance> advances_;
61   bool patched_;
62 
63   DISALLOW_COPY_AND_ASSIGN(LazyDebugFrameOpCodeWriter);
64 };
65 
66 }  // namespace dwarf
67 }  // namespace art
68 
69 #endif  // ART_COMPILER_DEX_QUICK_LAZY_DEBUG_FRAME_OPCODE_WRITER_H_
70