| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 void Safepoint::DefinePointerRegister(Register reg) { | 119 void Safepoint::DefinePointerRegister(Register reg) { |
| 120 registers_->Add(reg.code()); | 120 registers_->Add(reg.code()); |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 Safepoint SafepointTableBuilder::DefineSafepoint( | 124 Safepoint SafepointTableBuilder::DefineSafepoint( |
| 125 Assembler* assembler, Safepoint::Kind kind, int arguments, | 125 Assembler* assembler, |
| 126 int deoptimization_index) { | 126 Safepoint::Kind kind, |
| 127 ASSERT(deoptimization_index != -1); | 127 int arguments, |
| 128 Safepoint::DeoptMode deopt_mode) { |
| 128 ASSERT(arguments >= 0); | 129 ASSERT(arguments >= 0); |
| 129 DeoptimizationInfo pc_and_deoptimization_index; | 130 DeoptimizationInfo info; |
| 130 pc_and_deoptimization_index.pc = assembler->pc_offset(); | 131 info.pc = assembler->pc_offset(); |
| 131 pc_and_deoptimization_index.deoptimization_index = deoptimization_index; | 132 info.arguments = arguments; |
| 132 pc_and_deoptimization_index.pc_after_gap = assembler->pc_offset(); | 133 info.has_doubles = (kind & Safepoint::kWithDoubles); |
| 133 pc_and_deoptimization_index.arguments = arguments; | 134 deoptimization_info_.Add(info); |
| 134 pc_and_deoptimization_index.has_doubles = (kind & Safepoint::kWithDoubles); | 135 deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex); |
| 135 deoptimization_info_.Add(pc_and_deoptimization_index); | 136 if (deopt_mode == Safepoint::kNoLazyDeopt) { |
| 137 last_lazy_safepoint_ = deopt_index_list_.length(); |
| 138 } |
| 136 indexes_.Add(new ZoneList<int>(8)); | 139 indexes_.Add(new ZoneList<int>(8)); |
| 137 registers_.Add((kind & Safepoint::kWithRegisters) | 140 registers_.Add((kind & Safepoint::kWithRegisters) |
| 138 ? new ZoneList<int>(4) | 141 ? new ZoneList<int>(4) |
| 139 : NULL); | 142 : NULL); |
| 140 return Safepoint(indexes_.last(), registers_.last()); | 143 return Safepoint(indexes_.last(), registers_.last()); |
| 141 } | 144 } |
| 142 | 145 |
| 143 | 146 |
| 147 void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) { |
| 148 while (last_lazy_safepoint_ < deopt_index_list_.length()) { |
| 149 deopt_index_list_[last_lazy_safepoint_++] = index; |
| 150 } |
| 151 } |
| 152 |
| 144 unsigned SafepointTableBuilder::GetCodeOffset() const { | 153 unsigned SafepointTableBuilder::GetCodeOffset() const { |
| 145 ASSERT(emitted_); | 154 ASSERT(emitted_); |
| 146 return offset_; | 155 return offset_; |
| 147 } | 156 } |
| 148 | 157 |
| 149 | 158 |
| 150 void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { | 159 void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { |
| 151 // For lazy deoptimization we need space to patch a call after every call. | 160 // For lazy deoptimization we need space to patch a call after every call. |
| 152 // Ensure there is always space for such patching, even if the code ends | 161 // Ensure there is always space for such patching, even if the code ends |
| 153 // in a call. | 162 // in a call. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 166 | 175 |
| 167 // Compute the number of bytes per safepoint entry. | 176 // Compute the number of bytes per safepoint entry. |
| 168 int bytes_per_entry = | 177 int bytes_per_entry = |
| 169 RoundUp(bits_per_entry, kBitsPerByte) >> kBitsPerByteLog2; | 178 RoundUp(bits_per_entry, kBitsPerByte) >> kBitsPerByteLog2; |
| 170 | 179 |
| 171 // Emit the table header. | 180 // Emit the table header. |
| 172 int length = deoptimization_info_.length(); | 181 int length = deoptimization_info_.length(); |
| 173 assembler->dd(length); | 182 assembler->dd(length); |
| 174 assembler->dd(bytes_per_entry); | 183 assembler->dd(bytes_per_entry); |
| 175 | 184 |
| 176 // Emit sorted table of pc offsets together with deoptimization indexes and | 185 // Emit sorted table of pc offsets together with deoptimization indexes. |
| 177 // pc after gap information. | |
| 178 for (int i = 0; i < length; i++) { | 186 for (int i = 0; i < length; i++) { |
| 179 assembler->dd(deoptimization_info_[i].pc); | 187 assembler->dd(deoptimization_info_[i].pc); |
| 180 assembler->dd(EncodeExceptPC(deoptimization_info_[i])); | 188 assembler->dd(EncodeExceptPC(deoptimization_info_[i], |
| 189 deopt_index_list_[i])); |
| 181 } | 190 } |
| 182 | 191 |
| 183 // Emit table of bitmaps. | 192 // Emit table of bitmaps. |
| 184 ZoneList<uint8_t> bits(bytes_per_entry); | 193 ZoneList<uint8_t> bits(bytes_per_entry); |
| 185 for (int i = 0; i < length; i++) { | 194 for (int i = 0; i < length; i++) { |
| 186 ZoneList<int>* indexes = indexes_[i]; | 195 ZoneList<int>* indexes = indexes_[i]; |
| 187 ZoneList<int>* registers = registers_[i]; | 196 ZoneList<int>* registers = registers_[i]; |
| 188 bits.Clear(); | 197 bits.Clear(); |
| 189 bits.AddBlock(0, bytes_per_entry); | 198 bits.AddBlock(0, bytes_per_entry); |
| 190 | 199 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 215 | 224 |
| 216 // Emit the bitmap for the current entry. | 225 // Emit the bitmap for the current entry. |
| 217 for (int k = 0; k < bytes_per_entry; k++) { | 226 for (int k = 0; k < bytes_per_entry; k++) { |
| 218 assembler->db(bits[k]); | 227 assembler->db(bits[k]); |
| 219 } | 228 } |
| 220 } | 229 } |
| 221 emitted_ = true; | 230 emitted_ = true; |
| 222 } | 231 } |
| 223 | 232 |
| 224 | 233 |
| 225 uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info) { | 234 uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info, |
| 226 unsigned index = info.deoptimization_index; | 235 unsigned index) { |
| 227 unsigned gap_size = info.pc_after_gap - info.pc; | |
| 228 uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index); | 236 uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index); |
| 229 encoding |= SafepointEntry::GapCodeSizeField::encode(gap_size); | |
| 230 encoding |= SafepointEntry::ArgumentsField::encode(info.arguments); | 237 encoding |= SafepointEntry::ArgumentsField::encode(info.arguments); |
| 231 encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles); | 238 encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles); |
| 232 return encoding; | 239 return encoding; |
| 233 } | 240 } |
| 234 | 241 |
| 235 | 242 |
| 236 int SafepointTableBuilder::CountShortDeoptimizationIntervals(unsigned limit) { | |
| 237 int result = 0; | |
| 238 if (!deoptimization_info_.is_empty()) { | |
| 239 unsigned previous_gap_end = deoptimization_info_[0].pc_after_gap; | |
| 240 for (int i = 1, n = deoptimization_info_.length(); i < n; i++) { | |
| 241 DeoptimizationInfo info = deoptimization_info_[i]; | |
| 242 if (static_cast<int>(info.deoptimization_index) != | |
| 243 Safepoint::kNoDeoptimizationIndex) { | |
| 244 if (previous_gap_end + limit > info.pc) { | |
| 245 result++; | |
| 246 } | |
| 247 previous_gap_end = info.pc_after_gap; | |
| 248 } | |
| 249 } | |
| 250 } | |
| 251 return result; | |
| 252 } | |
| 253 | |
| 254 | |
| 255 | 243 |
| 256 } } // namespace v8::internal | 244 } } // namespace v8::internal |
| OLD | NEW |