Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / safepoint-table.h
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_SAFEPOINT_TABLE_H_
6 #define V8_SAFEPOINT_TABLE_H_
7
8 #include "src/allocation.h"
9 #include "src/heap/heap.h"
10 #include "src/v8memory.h"
11 #include "src/zone.h"
12
13 namespace v8 {
14 namespace internal {
15
16 struct Register;
17
18 class SafepointEntry BASE_EMBEDDED {
19  public:
20   SafepointEntry() : info_(0), bits_(NULL) {}
21
22   SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {
23     DCHECK(is_valid());
24   }
25
26   bool is_valid() const { return bits_ != NULL; }
27
28   bool Equals(const SafepointEntry& other) const {
29     return info_ == other.info_ && bits_ == other.bits_;
30   }
31
32   void Reset() {
33     info_ = 0;
34     bits_ = NULL;
35   }
36
37   int deoptimization_index() const {
38     DCHECK(is_valid());
39     return DeoptimizationIndexField::decode(info_);
40   }
41
42   static const int kArgumentsFieldBits = 3;
43   static const int kSaveDoublesFieldBits = 1;
44   static const int kDeoptIndexBits =
45       32 - kArgumentsFieldBits - kSaveDoublesFieldBits;
46   class DeoptimizationIndexField:
47     public BitField<int, 0, kDeoptIndexBits> {};  // NOLINT
48   class ArgumentsField:
49     public BitField<unsigned,
50                     kDeoptIndexBits,
51                     kArgumentsFieldBits> {};  // NOLINT
52   class SaveDoublesField:
53     public BitField<bool,
54                     kDeoptIndexBits + kArgumentsFieldBits,
55                     kSaveDoublesFieldBits> { }; // NOLINT
56
57   int argument_count() const {
58     DCHECK(is_valid());
59     return ArgumentsField::decode(info_);
60   }
61
62   bool has_doubles() const {
63     DCHECK(is_valid());
64     return SaveDoublesField::decode(info_);
65   }
66
67   uint8_t* bits() {
68     DCHECK(is_valid());
69     return bits_;
70   }
71
72   bool HasRegisters() const;
73   bool HasRegisterAt(int reg_index) const;
74
75  private:
76   unsigned info_;
77   uint8_t* bits_;
78 };
79
80
81 class SafepointTable BASE_EMBEDDED {
82  public:
83   explicit SafepointTable(Code* code);
84
85   int size() const {
86     return kHeaderSize +
87            (length_ * (kPcAndDeoptimizationIndexSize + entry_size_));
88   }
89   unsigned length() const { return length_; }
90   unsigned entry_size() const { return entry_size_; }
91
92   unsigned GetPcOffset(unsigned index) const {
93     DCHECK(index < length_);
94     return Memory::uint32_at(GetPcOffsetLocation(index));
95   }
96
97   SafepointEntry GetEntry(unsigned index) const {
98     DCHECK(index < length_);
99     unsigned info = Memory::uint32_at(GetInfoLocation(index));
100     uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
101     return SafepointEntry(info, bits);
102   }
103
104   // Returns the entry for the given pc.
105   SafepointEntry FindEntry(Address pc) const;
106
107   void PrintEntry(unsigned index, std::ostream& os) const;  // NOLINT
108
109  private:
110   static const uint8_t kNoRegisters = 0xFF;
111
112   static const int kLengthOffset = 0;
113   static const int kEntrySizeOffset = kLengthOffset + kIntSize;
114   static const int kHeaderSize = kEntrySizeOffset + kIntSize;
115
116   static const int kPcSize = kIntSize;
117   static const int kDeoptimizationIndexSize = kIntSize;
118   static const int kPcAndDeoptimizationIndexSize =
119       kPcSize + kDeoptimizationIndexSize;
120
121   Address GetPcOffsetLocation(unsigned index) const {
122     return pc_and_deoptimization_indexes_ +
123            (index * kPcAndDeoptimizationIndexSize);
124   }
125
126   Address GetInfoLocation(unsigned index) const {
127     return GetPcOffsetLocation(index) + kPcSize;
128   }
129
130   static void PrintBits(std::ostream& os,  // NOLINT
131                         uint8_t byte, int digits);
132
133   DisallowHeapAllocation no_allocation_;
134   Code* code_;
135   unsigned length_;
136   unsigned entry_size_;
137
138   Address pc_and_deoptimization_indexes_;
139   Address entries_;
140
141   friend class SafepointTableBuilder;
142   friend class SafepointEntry;
143
144   DISALLOW_COPY_AND_ASSIGN(SafepointTable);
145 };
146
147
148 class Safepoint BASE_EMBEDDED {
149  public:
150   typedef enum {
151     kSimple = 0,
152     kWithRegisters = 1 << 0,
153     kWithDoubles = 1 << 1,
154     kWithRegistersAndDoubles = kWithRegisters | kWithDoubles
155   } Kind;
156
157   enum DeoptMode {
158     kNoLazyDeopt,
159     kLazyDeopt
160   };
161
162   static const int kNoDeoptimizationIndex =
163       (1 << (SafepointEntry::kDeoptIndexBits)) - 1;
164
165   void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); }
166   void DefinePointerRegister(Register reg, Zone* zone);
167
168  private:
169   Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers)
170       : indexes_(indexes), registers_(registers) {}
171   ZoneList<int>* indexes_;
172   ZoneList<int>* registers_;
173
174   friend class SafepointTableBuilder;
175 };
176
177
178 class SafepointTableBuilder BASE_EMBEDDED {
179  public:
180   explicit SafepointTableBuilder(Zone* zone)
181       : deoptimization_info_(32, zone),
182         deopt_index_list_(32, zone),
183         indexes_(32, zone),
184         registers_(32, zone),
185         emitted_(false),
186         last_lazy_safepoint_(0),
187         zone_(zone) { }
188
189   // Get the offset of the emitted safepoint table in the code.
190   unsigned GetCodeOffset() const;
191
192   // Define a new safepoint for the current position in the body.
193   Safepoint DefineSafepoint(Assembler* assembler,
194                             Safepoint::Kind kind,
195                             int arguments,
196                             Safepoint::DeoptMode mode);
197
198   // Record deoptimization index for lazy deoptimization for the last
199   // outstanding safepoints.
200   void RecordLazyDeoptimizationIndex(int index);
201   void BumpLastLazySafepointIndex() {
202     last_lazy_safepoint_ = deopt_index_list_.length();
203   }
204
205   // Emit the safepoint table after the body. The number of bits per
206   // entry must be enough to hold all the pointer indexes.
207   void Emit(Assembler* assembler, int bits_per_entry);
208
209
210  private:
211   struct DeoptimizationInfo {
212     unsigned pc;
213     unsigned arguments;
214     bool has_doubles;
215   };
216
217   uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
218
219   ZoneList<DeoptimizationInfo> deoptimization_info_;
220   ZoneList<unsigned> deopt_index_list_;
221   ZoneList<ZoneList<int>*> indexes_;
222   ZoneList<ZoneList<int>*> registers_;
223
224   unsigned offset_;
225   bool emitted_;
226   int last_lazy_safepoint_;
227
228   Zone* zone_;
229
230   DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder);
231 };
232
233 } }  // namespace v8::internal
234
235 #endif  // V8_SAFEPOINT_TABLE_H_