19 bool SafepointEntry::HasRegisters()
const {
23 for (
int i = 0;
i < num_reg_bytes;
i++) {
24 if (bits_[
i] != SafepointTable::kNoRegisters)
return true;
30 bool SafepointEntry::HasRegisterAt(
int reg_index)
const {
35 return (bits_[byte_index] & (1 << bit_index)) != 0;
39 SafepointTable::SafepointTable(Code* code) {
40 DCHECK(code->is_crankshafted());
42 Address header = code->instruction_start() + code->safepoint_table_offset();
45 pc_and_deoptimization_indexes_ = header + kHeaderSize;
46 entries_ = pc_and_deoptimization_indexes_ +
47 (length_ * kPcAndDeoptimizationIndexSize);
49 STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax ==
50 Safepoint::kNoDeoptimizationIndex);
54 SafepointEntry SafepointTable::FindEntry(
Address pc)
const {
55 unsigned pc_offset =
static_cast<unsigned>(
pc - code_->instruction_start());
56 for (
unsigned i = 0;
i < length();
i++) {
58 if (GetPcOffset(
i) == pc_offset)
return GetEntry(
i);
60 return SafepointEntry();
64 void SafepointTable::PrintEntry(
unsigned index, OStream& os)
const {
66 SafepointEntry entry =
GetEntry(index);
67 uint8_t* bits = entry.bits();
70 if (entry_size_ > 0) {
73 int last = entry_size_ - 1;
75 int last_bits = code_->stack_slots() - ((last - first) *
kBitsPerByte);
76 PrintBits(os, bits[last], last_bits);
79 if (!entry.HasRegisters())
return;
81 if (entry.HasRegisterAt(j)) {
89 void SafepointTable::PrintBits(OStream& os,
90 uint8_t
byte,
int digits) {
92 for (
int i = 0;
i < digits;
i++) {
93 os << (((
byte & (1 <<
i)) == 0) ?
"0" :
"1");
98 void Safepoint::DefinePointerRegister(Register reg, Zone* zone) {
99 registers_->Add(reg.code(), zone);
103 Safepoint SafepointTableBuilder::DefineSafepoint(
104 Assembler* assembler,
105 Safepoint::Kind kind,
107 Safepoint::DeoptMode deopt_mode) {
109 DeoptimizationInfo info;
110 info.pc = assembler->pc_offset();
111 info.arguments = arguments;
112 info.has_doubles = (kind & Safepoint::kWithDoubles);
113 deoptimization_info_.Add(info, zone_);
114 deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
115 if (deopt_mode == Safepoint::kNoLazyDeopt) {
116 last_lazy_safepoint_ = deopt_index_list_.length();
118 indexes_.Add(
new(zone_) ZoneList<int>(8, zone_), zone_);
119 registers_.Add((kind & Safepoint::kWithRegisters)
120 ?
new(zone_) ZoneList<int>(4, zone_)
123 return Safepoint(indexes_.last(), registers_.last());
127 void SafepointTableBuilder::RecordLazyDeoptimizationIndex(
int index) {
128 while (last_lazy_safepoint_ < deopt_index_list_.length()) {
129 deopt_index_list_[last_lazy_safepoint_++] = index;
133 unsigned SafepointTableBuilder::GetCodeOffset()
const {
139 void SafepointTableBuilder::Emit(Assembler* assembler,
int bits_per_entry) {
142 assembler->RecordComment(
";;; Safepoint table.");
143 offset_ = assembler->pc_offset();
149 int bytes_per_entry =
153 int length = deoptimization_info_.length();
154 assembler->dd(length);
155 assembler->dd(bytes_per_entry);
158 for (
int i = 0;
i < length;
i++) {
159 assembler->dd(deoptimization_info_[
i].
pc);
160 assembler->dd(EncodeExceptPC(deoptimization_info_[
i],
161 deopt_index_list_[
i]));
165 ZoneList<uint8_t> bits(bytes_per_entry, zone_);
166 for (
int i = 0;
i < length;
i++) {
167 ZoneList<int>* indexes = indexes_[
i];
168 ZoneList<int>* registers = registers_[
i];
170 bits.AddBlock(0, bytes_per_entry, zone_);
174 if (registers ==
NULL) {
176 for (
int j = 0; j < num_reg_bytes; j++) {
177 bits[j] = SafepointTable::kNoRegisters;
180 for (
int j = 0; j < registers->length(); j++) {
181 int index = registers->at(j);
185 bits[byte_index] |= (1 << bit_index);
190 for (
int j = 0; j < indexes->length(); j++) {
191 int index = bits_per_entry - 1 - indexes->at(j);
194 bits[byte_index] |= (1U << bit_index);
198 for (
int k = 0; k < bytes_per_entry; k++) {
199 assembler->db(bits[k]);
206 uint32_t SafepointTableBuilder::EncodeExceptPC(
const DeoptimizationInfo& info,
208 uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index);
209 encoding |= SafepointEntry::ArgumentsField::encode(info.arguments);
210 encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles);
virtual const char * NameOfCPURegister(int reg) const
static uint32_t & uint32_at(Address addr)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
static uchar GetEntry(int32_t entry)
const int kNumSafepointRegisters
const int kBitsPerByteLog2
static void RoundUp(Vector< char > buffer, int *length, int *decimal_point)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
bool IsAligned(T value, U alignment)
Debugger support for the V8 JavaScript engine.