OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 12 matching lines...) Expand all Loading... | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_SAFEPOINT_TABLE_H_ | 28 #ifndef V8_SAFEPOINT_TABLE_H_ |
29 #define V8_SAFEPOINT_TABLE_H_ | 29 #define V8_SAFEPOINT_TABLE_H_ |
30 | 30 |
31 #include "v8.h" | 31 #include "v8.h" |
32 | 32 |
33 #include "macro-assembler.h" | 33 #include "heap.h" |
34 #include "zone.h" | 34 #include "zone.h" |
35 #include "zone-inl.h" | 35 #include "zone-inl.h" |
36 | 36 |
37 namespace v8 { | 37 namespace v8 { |
38 namespace internal { | 38 namespace internal { |
39 | 39 |
40 struct Register; | |
41 | |
42 class SafepointEntry BASE_EMBEDDED { | |
43 public: | |
44 SafepointEntry() : info_(0), bits_(NULL) {} | |
45 | |
46 SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {} | |
47 | |
48 bool is_valid() const { return bits_ != NULL; } | |
49 | |
50 bool Equals(const SafepointEntry& other) const { | |
51 return info_ == other.info_ && bits_ == other.bits_; | |
52 } | |
53 | |
54 void Reset() { | |
55 info_ = 0; | |
56 bits_ = NULL; | |
57 } | |
58 | |
59 int deoptimization_index() const { | |
60 ASSERT(is_valid()); | |
61 return DeoptimizationIndexField::decode(info_); | |
62 } | |
63 | |
64 int gap_code_size() const { | |
65 ASSERT(is_valid()); | |
66 return GapCodeSizeField::decode(info_); | |
67 } | |
68 | |
69 int argument_count() const { | |
70 ASSERT(is_valid()); | |
71 return ArgumentsField::decode(info_); | |
72 } | |
73 | |
74 uint8_t* bits() { | |
75 ASSERT(is_valid()); | |
76 return bits_; | |
77 } | |
78 | |
79 bool HasRegisters() const; | |
80 bool HasRegisterAt(int reg_index) const; | |
81 | |
82 // Reserve 13 bits for the gap code size. On ARM a constant pool can be | |
83 // emitted when generating the gap code. The size of the const pool is less | |
84 // than what can be represented in 12 bits, so 13 bits gives room for having | |
85 // instructions before potentially emitting a constant pool. | |
86 static const int kGapCodeSizeBits = 13; | |
87 static const int kArgumentsFieldBits = 3; | |
88 static const int kDeoptIndexBits = | |
89 32 - kGapCodeSizeBits - kArgumentsFieldBits; | |
90 class GapCodeSizeField: public BitField<unsigned, 0, kGapCodeSizeBits> {}; | |
91 class DeoptimizationIndexField: public BitField<int, | |
92 kGapCodeSizeBits, | |
93 kDeoptIndexBits> {}; // NOLIN T | |
fschneider
2011/01/12 09:57:02
Is the NO_LINT needed? This looks like perfectly f
Vitaly Repeshko
2011/01/12 14:14:35
Cpplint doesn't like the semicolon after the closi
| |
94 class ArgumentsField: public BitField<unsigned, | |
95 kGapCodeSizeBits + kDeoptIndexBits, | |
96 kArgumentsFieldBits> {}; // NOLINT | |
97 private: | |
98 unsigned info_; | |
99 uint8_t* bits_; | |
100 }; | |
101 | |
102 | |
40 class SafepointTable BASE_EMBEDDED { | 103 class SafepointTable BASE_EMBEDDED { |
41 public: | 104 public: |
42 explicit SafepointTable(Code* code); | 105 explicit SafepointTable(Code* code); |
43 | 106 |
44 int size() const { | 107 int size() const { |
45 return kHeaderSize + | 108 return kHeaderSize + |
46 (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); } | 109 (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); } |
47 unsigned length() const { return length_; } | 110 unsigned length() const { return length_; } |
48 unsigned entry_size() const { return entry_size_; } | 111 unsigned entry_size() const { return entry_size_; } |
49 | 112 |
50 unsigned GetPcOffset(unsigned index) const { | 113 unsigned GetPcOffset(unsigned index) const { |
51 ASSERT(index < length_); | 114 ASSERT(index < length_); |
52 return Memory::uint32_at(GetPcOffsetLocation(index)); | 115 return Memory::uint32_at(GetPcOffsetLocation(index)); |
53 } | 116 } |
54 | 117 |
55 int GetDeoptimizationIndex(unsigned index) const { | 118 SafepointEntry GetEntry(unsigned index) const { |
56 ASSERT(index < length_); | 119 ASSERT(index < length_); |
57 unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index)); | 120 unsigned info = Memory::uint32_at(GetInfoLocation(index)); |
58 return DeoptimizationIndexField::decode(value); | 121 uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_)); |
122 return SafepointEntry(info, bits); | |
59 } | 123 } |
60 | 124 |
61 unsigned GetGapCodeSize(unsigned index) const { | 125 // Returns the entry index for the given pc. |
62 ASSERT(index < length_); | 126 SafepointEntry FindEntry(Address pc) const; |
63 unsigned value = Memory::uint32_at(GetDeoptimizationLocation(index)); | |
64 return GapCodeSizeField::decode(value); | |
65 } | |
66 | |
67 uint8_t* GetEntry(unsigned index) const { | |
68 ASSERT(index < length_); | |
69 return &Memory::uint8_at(entries_ + (index * entry_size_)); | |
70 } | |
71 | |
72 // Reserve 13 bits for the gap code size. On ARM a constant pool can be | |
73 // emitted when generating the gap code. The size of the const pool is less | |
74 // than what can be represented in 12 bits, so 13 bits gives room for having | |
75 // instructions before potentially emitting a constant pool. | |
76 static const int kGapCodeSizeBits = 13; | |
77 static const int kDeoptIndexBits = 32 - kGapCodeSizeBits; | |
78 class GapCodeSizeField: public BitField<unsigned, 0, kGapCodeSizeBits> {}; | |
79 class DeoptimizationIndexField: public BitField<int, kGapCodeSizeBits, kDeoptI ndexBits> {}; // NOLINT | |
80 | |
81 static bool HasRegisters(uint8_t* entry); | |
82 static bool HasRegisterAt(uint8_t* entry, int reg_index); | |
83 | 127 |
84 void PrintEntry(unsigned index) const; | 128 void PrintEntry(unsigned index) const; |
85 | 129 |
86 private: | 130 private: |
87 static const uint8_t kNoRegisters = 0xFF; | 131 static const uint8_t kNoRegisters = 0xFF; |
88 | 132 |
89 static const int kLengthOffset = 0; | 133 static const int kLengthOffset = 0; |
90 static const int kEntrySizeOffset = kLengthOffset + kIntSize; | 134 static const int kEntrySizeOffset = kLengthOffset + kIntSize; |
91 static const int kHeaderSize = kEntrySizeOffset + kIntSize; | 135 static const int kHeaderSize = kEntrySizeOffset + kIntSize; |
92 | 136 |
93 static const int kPcSize = kIntSize; | 137 static const int kPcSize = kIntSize; |
94 static const int kDeoptimizationIndexSize = kIntSize; | 138 static const int kDeoptimizationIndexSize = kIntSize; |
95 static const int kPcAndDeoptimizationIndexSize = | 139 static const int kPcAndDeoptimizationIndexSize = |
96 kPcSize + kDeoptimizationIndexSize; | 140 kPcSize + kDeoptimizationIndexSize; |
97 | 141 |
98 Address GetPcOffsetLocation(unsigned index) const { | 142 Address GetPcOffsetLocation(unsigned index) const { |
99 return pc_and_deoptimization_indexes_ + | 143 return pc_and_deoptimization_indexes_ + |
100 (index * kPcAndDeoptimizationIndexSize); | 144 (index * kPcAndDeoptimizationIndexSize); |
101 } | 145 } |
102 | 146 |
103 Address GetDeoptimizationLocation(unsigned index) const { | 147 Address GetInfoLocation(unsigned index) const { |
104 return GetPcOffsetLocation(index) + kPcSize; | 148 return GetPcOffsetLocation(index) + kPcSize; |
105 } | 149 } |
106 | 150 |
107 static void PrintBits(uint8_t byte, int digits); | 151 static void PrintBits(uint8_t byte, int digits); |
108 | 152 |
109 AssertNoAllocation no_allocation_; | 153 AssertNoAllocation no_allocation_; |
110 Code* code_; | 154 Code* code_; |
111 unsigned length_; | 155 unsigned length_; |
112 unsigned entry_size_; | 156 unsigned entry_size_; |
113 | 157 |
114 Address pc_and_deoptimization_indexes_; | 158 Address pc_and_deoptimization_indexes_; |
115 Address entries_; | 159 Address entries_; |
116 | 160 |
117 friend class SafepointTableBuilder; | 161 friend class SafepointTableBuilder; |
162 friend class SafepointEntry; | |
163 | |
164 DISALLOW_COPY_AND_ASSIGN(SafepointTable); | |
118 }; | 165 }; |
119 | 166 |
120 | 167 |
121 class Safepoint BASE_EMBEDDED { | 168 class Safepoint BASE_EMBEDDED { |
122 public: | 169 public: |
123 static const int kNoDeoptimizationIndex = | 170 static const int kNoDeoptimizationIndex = |
124 (1 << (SafepointTable::kDeoptIndexBits)) - 1; | 171 (1 << (SafepointEntry::kDeoptIndexBits)) - 1; |
125 | 172 |
126 void DefinePointerSlot(int index) { indexes_->Add(index); } | 173 void DefinePointerSlot(int index) { indexes_->Add(index); } |
127 void DefinePointerRegister(Register reg) { registers_->Add(reg.code()); } | 174 void DefinePointerRegister(Register reg); |
128 | 175 |
129 private: | 176 private: |
130 Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) : | 177 Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) : |
131 indexes_(indexes), registers_(registers) { } | 178 indexes_(indexes), registers_(registers) { } |
132 ZoneList<int>* indexes_; | 179 ZoneList<int>* indexes_; |
133 ZoneList<int>* registers_; | 180 ZoneList<int>* registers_; |
134 | 181 |
135 friend class SafepointTableBuilder; | 182 friend class SafepointTableBuilder; |
136 }; | 183 }; |
137 | 184 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 | 217 |
171 // Emit the safepoint table after the body. The number of bits per | 218 // Emit the safepoint table after the body. The number of bits per |
172 // entry must be enough to hold all the pointer indexes. | 219 // entry must be enough to hold all the pointer indexes. |
173 void Emit(Assembler* assembler, int bits_per_entry); | 220 void Emit(Assembler* assembler, int bits_per_entry); |
174 | 221 |
175 private: | 222 private: |
176 struct DeoptimizationInfo { | 223 struct DeoptimizationInfo { |
177 unsigned pc; | 224 unsigned pc; |
178 unsigned deoptimization_index; | 225 unsigned deoptimization_index; |
179 unsigned pc_after_gap; | 226 unsigned pc_after_gap; |
227 unsigned arguments; | |
180 }; | 228 }; |
181 | 229 |
182 uint32_t EncodeDeoptimizationIndexAndGap(DeoptimizationInfo info); | 230 uint32_t EncodeExceptPC(const DeoptimizationInfo& info); |
183 | 231 |
184 ZoneList<DeoptimizationInfo> deoptimization_info_; | 232 ZoneList<DeoptimizationInfo> deoptimization_info_; |
185 ZoneList<ZoneList<int>*> indexes_; | 233 ZoneList<ZoneList<int>*> indexes_; |
186 ZoneList<ZoneList<int>*> registers_; | 234 ZoneList<ZoneList<int>*> registers_; |
187 | 235 |
188 bool emitted_; | 236 bool emitted_; |
189 unsigned offset_; | 237 unsigned offset_; |
190 | 238 |
191 DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder); | 239 DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder); |
192 }; | 240 }; |
193 | 241 |
194 } } // namespace v8::internal | 242 } } // namespace v8::internal |
195 | 243 |
196 #endif // V8_SAFEPOINT_TABLE_H_ | 244 #endif // V8_SAFEPOINT_TABLE_H_ |
OLD | NEW |