OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/safepoint-table.h" | 7 #include "src/safepoint-table.h" |
8 | 8 |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
11 #include "src/macro-assembler.h" | 11 #include "src/macro-assembler.h" |
12 #include "src/ostreams.h" | 12 #include "src/ostreams.h" |
13 #include "src/zone-inl.h" | 13 #include "src/zone-inl.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 | 18 |
19 bool SafepointEntry::HasRegisters() const { | 19 bool SafepointEntry::HasRegisters() const { |
20 ASSERT(is_valid()); | 20 DCHECK(is_valid()); |
21 ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte)); | 21 DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte)); |
22 const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2; | 22 const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2; |
23 for (int i = 0; i < num_reg_bytes; i++) { | 23 for (int i = 0; i < num_reg_bytes; i++) { |
24 if (bits_[i] != SafepointTable::kNoRegisters) return true; | 24 if (bits_[i] != SafepointTable::kNoRegisters) return true; |
25 } | 25 } |
26 return false; | 26 return false; |
27 } | 27 } |
28 | 28 |
29 | 29 |
30 bool SafepointEntry::HasRegisterAt(int reg_index) const { | 30 bool SafepointEntry::HasRegisterAt(int reg_index) const { |
31 ASSERT(is_valid()); | 31 DCHECK(is_valid()); |
32 ASSERT(reg_index >= 0 && reg_index < kNumSafepointRegisters); | 32 DCHECK(reg_index >= 0 && reg_index < kNumSafepointRegisters); |
33 int byte_index = reg_index >> kBitsPerByteLog2; | 33 int byte_index = reg_index >> kBitsPerByteLog2; |
34 int bit_index = reg_index & (kBitsPerByte - 1); | 34 int bit_index = reg_index & (kBitsPerByte - 1); |
35 return (bits_[byte_index] & (1 << bit_index)) != 0; | 35 return (bits_[byte_index] & (1 << bit_index)) != 0; |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 SafepointTable::SafepointTable(Code* code) { | 39 SafepointTable::SafepointTable(Code* code) { |
40 ASSERT(code->is_crankshafted()); | 40 DCHECK(code->is_crankshafted()); |
41 code_ = code; | 41 code_ = code; |
42 Address header = code->instruction_start() + code->safepoint_table_offset(); | 42 Address header = code->instruction_start() + code->safepoint_table_offset(); |
43 length_ = Memory::uint32_at(header + kLengthOffset); | 43 length_ = Memory::uint32_at(header + kLengthOffset); |
44 entry_size_ = Memory::uint32_at(header + kEntrySizeOffset); | 44 entry_size_ = Memory::uint32_at(header + kEntrySizeOffset); |
45 pc_and_deoptimization_indexes_ = header + kHeaderSize; | 45 pc_and_deoptimization_indexes_ = header + kHeaderSize; |
46 entries_ = pc_and_deoptimization_indexes_ + | 46 entries_ = pc_and_deoptimization_indexes_ + |
47 (length_ * kPcAndDeoptimizationIndexSize); | 47 (length_ * kPcAndDeoptimizationIndexSize); |
48 ASSERT(entry_size_ > 0); | 48 DCHECK(entry_size_ > 0); |
49 STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax == | 49 STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax == |
50 Safepoint::kNoDeoptimizationIndex); | 50 Safepoint::kNoDeoptimizationIndex); |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 SafepointEntry SafepointTable::FindEntry(Address pc) const { | 54 SafepointEntry SafepointTable::FindEntry(Address pc) const { |
55 unsigned pc_offset = static_cast<unsigned>(pc - code_->instruction_start()); | 55 unsigned pc_offset = static_cast<unsigned>(pc - code_->instruction_start()); |
56 for (unsigned i = 0; i < length(); i++) { | 56 for (unsigned i = 0; i < length(); i++) { |
57 // TODO(kasperl): Replace the linear search with binary search. | 57 // TODO(kasperl): Replace the linear search with binary search. |
58 if (GetPcOffset(i) == pc_offset) return GetEntry(i); | 58 if (GetPcOffset(i) == pc_offset) return GetEntry(i); |
59 } | 59 } |
60 return SafepointEntry(); | 60 return SafepointEntry(); |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 void SafepointTable::PrintEntry(unsigned index, OStream& os) const { // NOLINT | 64 void SafepointTable::PrintEntry(unsigned index, OStream& os) const { // NOLINT |
65 disasm::NameConverter converter; | 65 disasm::NameConverter converter; |
66 SafepointEntry entry = GetEntry(index); | 66 SafepointEntry entry = GetEntry(index); |
67 uint8_t* bits = entry.bits(); | 67 uint8_t* bits = entry.bits(); |
68 | 68 |
69 // Print the stack slot bits. | 69 // Print the stack slot bits. |
70 if (entry_size_ > 0) { | 70 if (entry_size_ > 0) { |
71 ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte)); | 71 DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte)); |
72 const int first = kNumSafepointRegisters >> kBitsPerByteLog2; | 72 const int first = kNumSafepointRegisters >> kBitsPerByteLog2; |
73 int last = entry_size_ - 1; | 73 int last = entry_size_ - 1; |
74 for (int i = first; i < last; i++) PrintBits(os, bits[i], kBitsPerByte); | 74 for (int i = first; i < last; i++) PrintBits(os, bits[i], kBitsPerByte); |
75 int last_bits = code_->stack_slots() - ((last - first) * kBitsPerByte); | 75 int last_bits = code_->stack_slots() - ((last - first) * kBitsPerByte); |
76 PrintBits(os, bits[last], last_bits); | 76 PrintBits(os, bits[last], last_bits); |
77 | 77 |
78 // Print the registers (if any). | 78 // Print the registers (if any). |
79 if (!entry.HasRegisters()) return; | 79 if (!entry.HasRegisters()) return; |
80 for (int j = 0; j < kNumSafepointRegisters; j++) { | 80 for (int j = 0; j < kNumSafepointRegisters; j++) { |
81 if (entry.HasRegisterAt(j)) { | 81 if (entry.HasRegisterAt(j)) { |
82 os << " | " << converter.NameOfCPURegister(j); | 82 os << " | " << converter.NameOfCPURegister(j); |
83 } | 83 } |
84 } | 84 } |
85 } | 85 } |
86 } | 86 } |
87 | 87 |
88 | 88 |
89 void SafepointTable::PrintBits(OStream& os, // NOLINT | 89 void SafepointTable::PrintBits(OStream& os, // NOLINT |
90 uint8_t byte, int digits) { | 90 uint8_t byte, int digits) { |
91 ASSERT(digits >= 0 && digits <= kBitsPerByte); | 91 DCHECK(digits >= 0 && digits <= kBitsPerByte); |
92 for (int i = 0; i < digits; i++) { | 92 for (int i = 0; i < digits; i++) { |
93 os << (((byte & (1 << i)) == 0) ? "0" : "1"); | 93 os << (((byte & (1 << i)) == 0) ? "0" : "1"); |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 | 97 |
98 void Safepoint::DefinePointerRegister(Register reg, Zone* zone) { | 98 void Safepoint::DefinePointerRegister(Register reg, Zone* zone) { |
99 registers_->Add(reg.code(), zone); | 99 registers_->Add(reg.code(), zone); |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 Safepoint SafepointTableBuilder::DefineSafepoint( | 103 Safepoint SafepointTableBuilder::DefineSafepoint( |
104 Assembler* assembler, | 104 Assembler* assembler, |
105 Safepoint::Kind kind, | 105 Safepoint::Kind kind, |
106 int arguments, | 106 int arguments, |
107 Safepoint::DeoptMode deopt_mode) { | 107 Safepoint::DeoptMode deopt_mode) { |
108 ASSERT(arguments >= 0); | 108 DCHECK(arguments >= 0); |
109 DeoptimizationInfo info; | 109 DeoptimizationInfo info; |
110 info.pc = assembler->pc_offset(); | 110 info.pc = assembler->pc_offset(); |
111 info.arguments = arguments; | 111 info.arguments = arguments; |
112 info.has_doubles = (kind & Safepoint::kWithDoubles); | 112 info.has_doubles = (kind & Safepoint::kWithDoubles); |
113 deoptimization_info_.Add(info, zone_); | 113 deoptimization_info_.Add(info, zone_); |
114 deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_); | 114 deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_); |
115 if (deopt_mode == Safepoint::kNoLazyDeopt) { | 115 if (deopt_mode == Safepoint::kNoLazyDeopt) { |
116 last_lazy_safepoint_ = deopt_index_list_.length(); | 116 last_lazy_safepoint_ = deopt_index_list_.length(); |
117 } | 117 } |
118 indexes_.Add(new(zone_) ZoneList<int>(8, zone_), zone_); | 118 indexes_.Add(new(zone_) ZoneList<int>(8, zone_), zone_); |
119 registers_.Add((kind & Safepoint::kWithRegisters) | 119 registers_.Add((kind & Safepoint::kWithRegisters) |
120 ? new(zone_) ZoneList<int>(4, zone_) | 120 ? new(zone_) ZoneList<int>(4, zone_) |
121 : NULL, | 121 : NULL, |
122 zone_); | 122 zone_); |
123 return Safepoint(indexes_.last(), registers_.last()); | 123 return Safepoint(indexes_.last(), registers_.last()); |
124 } | 124 } |
125 | 125 |
126 | 126 |
127 void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) { | 127 void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) { |
128 while (last_lazy_safepoint_ < deopt_index_list_.length()) { | 128 while (last_lazy_safepoint_ < deopt_index_list_.length()) { |
129 deopt_index_list_[last_lazy_safepoint_++] = index; | 129 deopt_index_list_[last_lazy_safepoint_++] = index; |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 unsigned SafepointTableBuilder::GetCodeOffset() const { | 133 unsigned SafepointTableBuilder::GetCodeOffset() const { |
134 ASSERT(emitted_); | 134 DCHECK(emitted_); |
135 return offset_; | 135 return offset_; |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { | 139 void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { |
140 // Make sure the safepoint table is properly aligned. Pad with nops. | 140 // Make sure the safepoint table is properly aligned. Pad with nops. |
141 assembler->Align(kIntSize); | 141 assembler->Align(kIntSize); |
142 assembler->RecordComment(";;; Safepoint table."); | 142 assembler->RecordComment(";;; Safepoint table."); |
143 offset_ = assembler->pc_offset(); | 143 offset_ = assembler->pc_offset(); |
144 | 144 |
(...skipping 18 matching lines...) Expand all Loading... |
163 | 163 |
164 // Emit table of bitmaps. | 164 // Emit table of bitmaps. |
165 ZoneList<uint8_t> bits(bytes_per_entry, zone_); | 165 ZoneList<uint8_t> bits(bytes_per_entry, zone_); |
166 for (int i = 0; i < length; i++) { | 166 for (int i = 0; i < length; i++) { |
167 ZoneList<int>* indexes = indexes_[i]; | 167 ZoneList<int>* indexes = indexes_[i]; |
168 ZoneList<int>* registers = registers_[i]; | 168 ZoneList<int>* registers = registers_[i]; |
169 bits.Clear(); | 169 bits.Clear(); |
170 bits.AddBlock(0, bytes_per_entry, zone_); | 170 bits.AddBlock(0, bytes_per_entry, zone_); |
171 | 171 |
172 // Run through the registers (if any). | 172 // Run through the registers (if any). |
173 ASSERT(IsAligned(kNumSafepointRegisters, kBitsPerByte)); | 173 DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte)); |
174 if (registers == NULL) { | 174 if (registers == NULL) { |
175 const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2; | 175 const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2; |
176 for (int j = 0; j < num_reg_bytes; j++) { | 176 for (int j = 0; j < num_reg_bytes; j++) { |
177 bits[j] = SafepointTable::kNoRegisters; | 177 bits[j] = SafepointTable::kNoRegisters; |
178 } | 178 } |
179 } else { | 179 } else { |
180 for (int j = 0; j < registers->length(); j++) { | 180 for (int j = 0; j < registers->length(); j++) { |
181 int index = registers->at(j); | 181 int index = registers->at(j); |
182 ASSERT(index >= 0 && index < kNumSafepointRegisters); | 182 DCHECK(index >= 0 && index < kNumSafepointRegisters); |
183 int byte_index = index >> kBitsPerByteLog2; | 183 int byte_index = index >> kBitsPerByteLog2; |
184 int bit_index = index & (kBitsPerByte - 1); | 184 int bit_index = index & (kBitsPerByte - 1); |
185 bits[byte_index] |= (1 << bit_index); | 185 bits[byte_index] |= (1 << bit_index); |
186 } | 186 } |
187 } | 187 } |
188 | 188 |
189 // Run through the indexes and build a bitmap. | 189 // Run through the indexes and build a bitmap. |
190 for (int j = 0; j < indexes->length(); j++) { | 190 for (int j = 0; j < indexes->length(); j++) { |
191 int index = bits_per_entry - 1 - indexes->at(j); | 191 int index = bits_per_entry - 1 - indexes->at(j); |
192 int byte_index = index >> kBitsPerByteLog2; | 192 int byte_index = index >> kBitsPerByteLog2; |
(...skipping 14 matching lines...) Expand all Loading... |
207 unsigned index) { | 207 unsigned index) { |
208 uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index); | 208 uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index); |
209 encoding |= SafepointEntry::ArgumentsField::encode(info.arguments); | 209 encoding |= SafepointEntry::ArgumentsField::encode(info.arguments); |
210 encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles); | 210 encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles); |
211 return encoding; | 211 return encoding; |
212 } | 212 } |
213 | 213 |
214 | 214 |
215 | 215 |
216 } } // namespace v8::internal | 216 } } // namespace v8::internal |
OLD | NEW |