#include "src/arm/constants-arm.h"
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/serialize.h"
namespace v8 {
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
// Record the emission of a constant pool.
//
__ stop("trap_on_deopt", condition);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
#include "src/arm64/instructions-arm64.h"
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/globals.h"
#include "src/serialize.h"
#include "src/utils.h"
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
int buffer_space() const;
__ Bind(&dont_trap);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to build frame, or restore caller doubles.
DCHECK(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
} else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
// Use signed delta-encoding for id.
- DCHECK(static_cast<int>(rinfo->data()) == rinfo->data());
+ DCHECK_EQ(static_cast<int>(rinfo->data()), rinfo->data());
int id_delta = static_cast<int>(rinfo->data()) - last_id_;
// Check if delta is small enough to fit in a tagged byte.
if (is_intn(id_delta, kSmallDataBits)) {
WriteTaggedData(rinfo->data(), kDeoptReasonTag);
} else if (RelocInfo::IsPosition(rmode)) {
// Use signed delta-encoding for position.
- DCHECK(static_cast<int>(rinfo->data()) == rinfo->data());
+ DCHECK_EQ(static_cast<int>(rinfo->data()), rinfo->data());
int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
if (rmode == RelocInfo::STATEMENT_POSITION) {
WritePosition(pc_delta, pos_delta, rmode);
} else {
- DCHECK(rmode == RelocInfo::POSITION);
+ DCHECK_EQ(rmode, RelocInfo::POSITION);
if (pc_delta != 0 || last_mode_ != RelocInfo::POSITION) {
FlushPosition();
next_position_candidate_pc_delta_ = pc_delta;
// Platform specific but identical code for all the platforms.
-void Assembler::RecordDeoptReason(const int reason, const int raw_position) {
+void Assembler::RecordDeoptReason(const int reason,
+ const SourcePosition position) {
if (FLAG_trace_deopt || isolate()->cpu_profiler()->is_profiling()) {
EnsureSpace ensure_space(this);
+ int raw_position = position.IsUnknown() ? 0 : position.raw();
RecordRelocInfo(RelocInfo::POSITION, raw_position);
RecordRelocInfo(RelocInfo::DEOPT_REASON, reason);
}
// script start.
class SourcePosition {
public:
- SourcePosition(const SourcePosition& other) : value_(other.value_) {}
-
- static SourcePosition Unknown() { return SourcePosition(kNoPosition); }
+ static SourcePosition Unknown() {
+ return SourcePosition::FromRaw(kNoPosition);
+ }
bool IsUnknown() const { return value_ == kNoPosition; }
// Offset from the start of the inlined function.
typedef BitField<uint32_t, 9, 23> PositionField;
- explicit SourcePosition(uint32_t value) : value_(value) {}
-
friend class HPositionInfo;
- friend class LCodeGenBase;
+ friend class Deoptimizer;
+
+ static SourcePosition FromRaw(uint32_t raw_position) {
+ SourcePosition position;
+ position.value_ = raw_position;
+ return position;
+ }
// If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField
// and PositionField.
void CodeDeoptEventRecord::UpdateCodeMap(CodeMap* code_map) {
CodeEntry* entry = code_map->FindEntry(start);
- if (entry != NULL) entry->set_deopt_info(deopt_reason, raw_position);
+ if (entry != NULL) entry->set_deopt_info(deopt_reason, position);
}
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, bailout_id);
rec->start = code->address();
rec->deopt_reason = Deoptimizer::GetDeoptReason(info.deopt_reason);
- rec->raw_position = info.raw_position;
+ rec->position = info.position;
processor_->Enqueue(evt_rec);
processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta);
}
#include "src/base/atomicops.h"
#include "src/base/platform/time.h"
#include "src/circular-queue.h"
+#include "src/compiler.h"
#include "src/sampler.h"
#include "src/unbound-queue.h"
public:
Address start;
const char* deopt_reason;
- int raw_position;
+ SourcePosition position;
INLINE(void UpdateCodeMap(CodeMap* code_map));
};
Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, int bailout_id) {
- int last_position = 0;
+ SourcePosition last_position = SourcePosition::Unknown();
Isolate* isolate = code->GetIsolate();
Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason;
int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) |
for (RelocIterator it(code, mask); !it.done(); it.next()) {
RelocInfo* info = it.rinfo();
if (info->rmode() == RelocInfo::POSITION) {
- last_position = static_cast<int>(info->data());
+ int raw_position = static_cast<int>(info->data());
+ last_position = raw_position ? SourcePosition::FromRaw(raw_position)
+ : SourcePosition::Unknown();
} else if (info->rmode() == RelocInfo::DEOPT_REASON) {
last_reason = static_cast<Deoptimizer::DeoptReason>(info->data());
} else if (last_reason != Deoptimizer::kNoReason) {
}
}
}
- return DeoptInfo(0, NULL, Deoptimizer::kNoReason);
+ return DeoptInfo(SourcePosition::Unknown(), NULL, Deoptimizer::kNoReason);
}
} } // namespace v8::internal
static const char* GetDeoptReason(DeoptReason deopt_reason);
struct DeoptInfo {
- DeoptInfo(int r, const char* m, DeoptReason d)
- : raw_position(r), mnemonic(m), deopt_reason(d) {}
+ DeoptInfo(SourcePosition position, const char* m, DeoptReason d)
+ : position(position), mnemonic(m), deopt_reason(d) {}
- int raw_position;
+ SourcePosition position;
const char* mnemonic;
DeoptReason deopt_reason;
};
if (has_operand_positions()) {
return operand_positions()[kInstructionPosIndex];
}
- return SourcePosition(static_cast<int>(UntagPosition(data_)));
+ return SourcePosition::FromRaw(static_cast<int>(UntagPosition(data_)));
}
void set_position(SourcePosition pos) {
#include <deque>
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/isolate.h"
#include "src/serialize.h"
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
// Writes a single byte or word of data in the code stream. Used for
// inline tables, e.g., jump-tables.
__ bind(&done);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
if (cc == no_condition && frame_is_built_) {
void LCodeGenBase::DeoptComment(const Deoptimizer::DeoptInfo& deopt_info) {
- masm()->RecordDeoptReason(deopt_info.deopt_reason, deopt_info.raw_position);
+ masm()->RecordDeoptReason(deopt_info.deopt_reason, deopt_info.position);
}
#include <set>
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/mips/constants-mips.h"
#include "src/serialize.h"
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
static int RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
__ bind(&skip);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
static int RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
intptr_t pc_delta);
__ bind(&skip);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
#include "src/codegen.h"
+#include "src/compiler.h"
#include "src/cpu-profiler.h"
#include "src/date.h"
#include "src/debug.h"
void Code::PrintDeoptLocation(FILE* out, int bailout_id) {
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, bailout_id);
- if (info.deopt_reason != Deoptimizer::kNoReason || info.raw_position != 0) {
- PrintF(out, " ;;; deoptimize at %d: %s\n", info.raw_position,
- Deoptimizer::GetDeoptReason(info.deopt_reason));
+ class SourcePosition pos = info.position;
+ if (info.deopt_reason != Deoptimizer::kNoReason || !pos.IsUnknown()) {
+ if (FLAG_hydrogen_track_positions) {
+ PrintF(out, " ;;; deoptimize at %d_%d: %s\n",
+ pos.inlining_id(), pos.position(),
+ Deoptimizer::GetDeoptReason(info.deopt_reason));
+ } else {
+ PrintF(out, " ;;; deoptimize at %d: %s\n", pos.raw(),
+ Deoptimizer::GetDeoptReason(info.deopt_reason));
+ }
}
}
#include <vector>
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/ppc/constants-ppc.h"
#include "src/serialize.h"
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
// Writes a single byte or word of data in the code stream. Used
// for inline tables, e.g., jump-tables.
__ stop("trap_on_deopt", cond, kDefaultStopCode, cr);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
no_frame_ranges_(NULL),
bailout_reason_(kEmptyBailoutReason),
deopt_reason_(kNoDeoptReason),
- deopt_location_(0),
+ deopt_position_(SourcePosition::Unknown()),
line_info_(line_info),
instruction_start_(instruction_start) {}
void ProfileNode::CollectDeoptInfo(CodeEntry* entry) {
- deopt_infos_.Add(DeoptInfo(entry->deopt_reason(), entry->deopt_location()));
+ deopt_infos_.Add(DeoptInfo(entry->deopt_reason(), entry->deopt_position()));
entry->clear_deopt_info();
}
base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number());
base::OS::Print("\n");
for (auto info : deopt_infos_) {
- base::OS::Print("%*s deopted at %d with reason '%s'\n", indent + 10, "",
- info.deopt_location, info.deopt_reason);
+ if (FLAG_hydrogen_track_positions) {
+ base::OS::Print("%*s deopted at %d_%d with reason '%s'\n", indent + 10,
+ "", info.deopt_position.inlining_id(),
+ info.deopt_position.position(), info.deopt_reason);
+ } else {
+ base::OS::Print("%*s deopted at %d with reason '%s'\n", indent + 10, "",
+ info.deopt_position.raw(), info.deopt_reason);
+ }
}
const char* bailout_reason = entry_->bailout_reason();
if (bailout_reason != GetBailoutReason(BailoutReason::kNoReason) &&
#include <map>
#include "include/v8-profiler.h"
#include "src/allocation.h"
+#include "src/compiler.h"
#include "src/hashmap.h"
#include "src/strings-storage.h"
}
const char* bailout_reason() const { return bailout_reason_; }
- void set_deopt_info(const char* deopt_reason, int location) {
- DCHECK(!deopt_location_);
+ void set_deopt_info(const char* deopt_reason, SourcePosition position) {
+ DCHECK(deopt_position_.IsUnknown());
deopt_reason_ = deopt_reason;
- deopt_location_ = location;
+ deopt_position_ = position;
}
const char* deopt_reason() const { return deopt_reason_; }
- int deopt_location() const { return deopt_location_; }
- bool has_deopt_info() const { return deopt_location_; }
+ SourcePosition deopt_position() const { return deopt_position_; }
+ bool has_deopt_info() const { return !deopt_position_.IsUnknown(); }
void clear_deopt_info() {
deopt_reason_ = kNoDeoptReason;
- deopt_location_ = 0;
+ deopt_position_ = SourcePosition::Unknown();
}
void FillFunctionInfo(SharedFunctionInfo* shared);
List<OffsetRange>* no_frame_ranges_;
const char* bailout_reason_;
const char* deopt_reason_;
- int deopt_location_;
+ SourcePosition deopt_position_;
JITLineInfoTable* line_info_;
Address instruction_start_;
class ProfileNode {
private:
struct DeoptInfo {
- DeoptInfo(const char* deopt_reason, int deopt_location)
- : deopt_reason(deopt_reason), deopt_location(deopt_location) {}
+ DeoptInfo(const char* deopt_reason, SourcePosition deopt_position)
+ : deopt_reason(deopt_reason), deopt_position(deopt_position) {}
DeoptInfo(const DeoptInfo& info)
: deopt_reason(info.deopt_reason),
- deopt_location(info.deopt_location) {}
+ deopt_position(info.deopt_position) {}
const char* deopt_reason;
- int deopt_location;
+ SourcePosition deopt_position;
};
public:
#include <deque>
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/serialize.h"
namespace v8 {
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
// Allocate a constant pool of the correct size for the generated code.
Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
__ bind(&done);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
#include <deque>
#include "src/assembler.h"
+#include "src/compiler.h"
#include "src/isolate.h"
#include "src/serialize.h"
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
- void RecordDeoptReason(const int reason, const int raw_position);
+ void RecordDeoptReason(const int reason, const SourcePosition position);
// Writes a single byte or word of data in the code stream. Used for
// inline tables, e.g., jump-tables.
__ bind(&done);
}
- Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(),
+ Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(),
instr->Mnemonic(), deopt_reason);
DCHECK(info()->IsStub() || frame_is_built_);
if (cc == no_condition && frame_is_built_) {