Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(524)

Side by Side Diff: src/safepoint-table.h

Issue 6125007: Allow arguments in safepoints with registers. (Closed)
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698