[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / safepoint-table.h
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_SAFEPOINT_TABLE_H_
29 #define V8_SAFEPOINT_TABLE_H_
30
31 #include "allocation.h"
32 #include "heap.h"
33 #include "v8memory.h"
34 #include "zone.h"
35
36 namespace v8 {
37 namespace internal {
38
39 struct Register;
40
41 class SafepointEntry BASE_EMBEDDED {
42  public:
43   SafepointEntry() : info_(0), bits_(NULL) {}
44
45   SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {
46     ASSERT(is_valid());
47   }
48
49   bool is_valid() const { return bits_ != NULL; }
50
51   bool Equals(const SafepointEntry& other) const {
52     return info_ == other.info_ && bits_ == other.bits_;
53   }
54
55   void Reset() {
56     info_ = 0;
57     bits_ = NULL;
58   }
59
60   int deoptimization_index() const {
61     ASSERT(is_valid());
62     return DeoptimizationIndexField::decode(info_);
63   }
64
65   static const int kArgumentsFieldBits = 3;
66   static const int kSaveDoublesFieldBits = 1;
67   static const int kDeoptIndexBits =
68       32 - kArgumentsFieldBits - kSaveDoublesFieldBits;
69   class DeoptimizationIndexField:
70     public BitField<int, 0, kDeoptIndexBits> {};  // NOLINT
71   class ArgumentsField:
72     public BitField<unsigned,
73                     kDeoptIndexBits,
74                     kArgumentsFieldBits> {};  // NOLINT
75   class SaveDoublesField:
76     public BitField<bool,
77                     kDeoptIndexBits + kArgumentsFieldBits,
78                     kSaveDoublesFieldBits> { }; // NOLINT
79
80   int argument_count() const {
81     ASSERT(is_valid());
82     return ArgumentsField::decode(info_);
83   }
84
85   bool has_doubles() const {
86     ASSERT(is_valid());
87     return SaveDoublesField::decode(info_);
88   }
89
90   uint8_t* bits() {
91     ASSERT(is_valid());
92     return bits_;
93   }
94
95   bool HasRegisters() const;
96   bool HasRegisterAt(int reg_index) const;
97
98  private:
99   unsigned info_;
100   uint8_t* bits_;
101 };
102
103
104 class SafepointTable BASE_EMBEDDED {
105  public:
106   explicit SafepointTable(Code* code);
107
108   int size() const {
109     return kHeaderSize +
110            (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
111   unsigned length() const { return length_; }
112   unsigned entry_size() const { return entry_size_; }
113
114   unsigned GetPcOffset(unsigned index) const {
115     ASSERT(index < length_);
116     return Memory::uint32_at(GetPcOffsetLocation(index));
117   }
118
119   SafepointEntry GetEntry(unsigned index) const {
120     ASSERT(index < length_);
121     unsigned info = Memory::uint32_at(GetInfoLocation(index));
122     uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
123     return SafepointEntry(info, bits);
124   }
125
126   // Returns the entry for the given pc.
127   SafepointEntry FindEntry(Address pc) const;
128
129   void PrintEntry(unsigned index) const;
130
131  private:
132   static const uint8_t kNoRegisters = 0xFF;
133
134   static const int kLengthOffset = 0;
135   static const int kEntrySizeOffset = kLengthOffset + kIntSize;
136   static const int kHeaderSize = kEntrySizeOffset + kIntSize;
137
138   static const int kPcSize = kIntSize;
139   static const int kDeoptimizationIndexSize = kIntSize;
140   static const int kPcAndDeoptimizationIndexSize =
141       kPcSize + kDeoptimizationIndexSize;
142
143   Address GetPcOffsetLocation(unsigned index) const {
144     return pc_and_deoptimization_indexes_ +
145            (index * kPcAndDeoptimizationIndexSize);
146   }
147
148   Address GetInfoLocation(unsigned index) const {
149     return GetPcOffsetLocation(index) + kPcSize;
150   }
151
152   static void PrintBits(uint8_t byte, int digits);
153
154   AssertNoAllocation no_allocation_;
155   Code* code_;
156   unsigned length_;
157   unsigned entry_size_;
158
159   Address pc_and_deoptimization_indexes_;
160   Address entries_;
161
162   friend class SafepointTableBuilder;
163   friend class SafepointEntry;
164
165   DISALLOW_COPY_AND_ASSIGN(SafepointTable);
166 };
167
168
169 class Safepoint BASE_EMBEDDED {
170  public:
171   typedef enum {
172     kSimple = 0,
173     kWithRegisters = 1 << 0,
174     kWithDoubles = 1 << 1,
175     kWithRegistersAndDoubles = kWithRegisters | kWithDoubles
176   } Kind;
177
178   enum DeoptMode {
179     kNoLazyDeopt,
180     kLazyDeopt
181   };
182
183   static const int kNoDeoptimizationIndex =
184       (1 << (SafepointEntry::kDeoptIndexBits)) - 1;
185
186   void DefinePointerSlot(int index) { indexes_->Add(index); }
187   void DefinePointerRegister(Register reg);
188
189  private:
190   Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) :
191       indexes_(indexes), registers_(registers) { }
192   ZoneList<int>* indexes_;
193   ZoneList<int>* registers_;
194
195   friend class SafepointTableBuilder;
196 };
197
198
199 class SafepointTableBuilder BASE_EMBEDDED {
200  public:
201   SafepointTableBuilder()
202       : deoptimization_info_(32),
203         deopt_index_list_(32),
204         indexes_(32),
205         registers_(32),
206         emitted_(false),
207         last_lazy_safepoint_(0) { }
208
209   // Get the offset of the emitted safepoint table in the code.
210   unsigned GetCodeOffset() const;
211
212   // Define a new safepoint for the current position in the body.
213   Safepoint DefineSafepoint(Assembler* assembler,
214                             Safepoint::Kind kind,
215                             int arguments,
216                             Safepoint::DeoptMode mode);
217
218   // Record deoptimization index for lazy deoptimization for the last
219   // outstanding safepoints.
220   void RecordLazyDeoptimizationIndex(int index);
221
222   // Emit the safepoint table after the body. The number of bits per
223   // entry must be enough to hold all the pointer indexes.
224   void Emit(Assembler* assembler, int bits_per_entry);
225
226
227  private:
228   struct DeoptimizationInfo {
229     unsigned pc;
230     unsigned arguments;
231     bool has_doubles;
232   };
233
234   uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
235
236   ZoneList<DeoptimizationInfo> deoptimization_info_;
237   ZoneList<unsigned> deopt_index_list_;
238   ZoneList<ZoneList<int>*> indexes_;
239   ZoneList<ZoneList<int>*> registers_;
240
241   unsigned offset_;
242   bool emitted_;
243   int last_lazy_safepoint_;
244
245   DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder);
246 };
247
248 } }  // namespace v8::internal
249
250 #endif  // V8_SAFEPOINT_TABLE_H_