From fb5857ceb81b0bfdc21f53e36679efb3e875e2ae Mon Sep 17 00:00:00 2001 From: "haitao.feng@intel.com" Date: Thu, 8 Aug 2013 02:16:12 +0000 Subject: [PATCH] Patch to enhance the source code line information for profiler. This patch is to enhance the source code line information for profiler. For the Hydrogen compilation, most of the source code line information is not copied from the HInstruction the to corresponding LInstruction. This patch defines one PositionBits field for LInstruction and copies the sorce code position value from the HInstruction. When Generating the native code, we use RecordPosition(..) function to write LInstruction's position value to position recorder. For the MIPS platform, I did not touch because I have no devices to verify the modification on it. R=danno@chromium.org Review URL: https://codereview.chromium.org/21042003 Patch from Chunyang Dai . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16114 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.cc | 1 + src/arm/lithium-arm.h | 34 +++++++++++++++++++++++--------- src/arm/lithium-codegen-arm.cc | 14 +++++++++++++ src/arm/lithium-codegen-arm.h | 6 +++++- src/ia32/lithium-codegen-ia32.cc | 14 +++++++++++++ src/ia32/lithium-codegen-ia32.h | 7 ++++++- src/ia32/lithium-ia32.cc | 1 + src/ia32/lithium-ia32.h | 27 +++++++++++++++++++------ src/x64/lithium-codegen-x64.cc | 14 +++++++++++++ src/x64/lithium-codegen-x64.h | 6 +++++- src/x64/lithium-x64.cc | 1 + src/x64/lithium-x64.h | 33 ++++++++++++++++++++++--------- 12 files changed, 131 insertions(+), 27 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 92909d4dba..08ba6e6d81 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -885,6 +885,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { } #endif + instr->set_position(position_); if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 5fa997cb6a..5b62b5739c 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -208,9 +208,12 @@ class LCodeGen; class LInstruction: public ZoneObject { public: LInstruction() - : environment_(NULL), - hydrogen_value_(NULL), - is_call_(false) { } + : environment_(NULL), + hydrogen_value_(NULL), + bit_field_(IsCallBits::encode(false)) { + set_position(RelocInfo::kNoPosition); + } + virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; @@ -249,20 +252,30 @@ class LInstruction: public ZoneObject { LPointerMap* pointer_map() const { return pointer_map_.get(); } bool HasPointerMap() const { return pointer_map_.is_set(); } + // The 31 bits PositionBits is used to store the int position value. And the + // position value may be RelocInfo::kNoPosition (-1). The accessor always + // +1/-1 so that the encoded value of position in bit_field_ is always >= 0 + // and can fit into the 31 bits PositionBits. + void set_position(int pos) { + bit_field_ = PositionBits::update(bit_field_, pos + 1); + } + int position() { return PositionBits::decode(bit_field_) - 1; } + void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } - void MarkAsCall() { is_call_ = true; } + void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } + bool IsCall() const { return IsCallBits::decode(bit_field_); } // Interface to the register allocator and iterators. - bool ClobbersTemps() const { return is_call_; } - bool ClobbersRegisters() const { return is_call_; } - bool ClobbersDoubleRegisters() const { return is_call_; } + bool ClobbersTemps() const { return IsCall(); } + bool ClobbersRegisters() const { return IsCall(); } + bool ClobbersDoubleRegisters() const { return IsCall(); } // Interface to the register allocator and iterators. - bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsCall() const { return IsCall(); } virtual bool HasResult() const = 0; virtual LOperand* result() const = 0; @@ -286,10 +299,13 @@ class LInstruction: public ZoneObject { virtual int TempCount() = 0; virtual LOperand* TempAt(int i) = 0; + class IsCallBits: public BitField {}; + class PositionBits: public BitField {}; + LEnvironment* environment_; SetOncePointer pointer_map_; HValue* hydrogen_value_; - bool is_call_; + int bit_field_; }; diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index d22bcb5910..4994975358 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -274,6 +274,8 @@ bool LCodeGen::GenerateBody() { instr->Mnemonic()); } + RecordAndUpdatePosition(instr->position()); + instr->CompileToNative(this); } EnsureSpaceForLazyDeopt(); @@ -287,6 +289,10 @@ bool LCodeGen::GenerateDeferredCode() { if (deferred_.length() > 0) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { LDeferredCode* code = deferred_[i]; + + int pos = instructions_->at(code->instruction_index())->position(); + RecordAndUpdatePosition(pos); + Comment(";;; <@%d,#%d> " "-------------------- Deferred %s --------------------", code->instruction_index(), @@ -997,6 +1003,14 @@ void LCodeGen::RecordPosition(int position) { } +void LCodeGen::RecordAndUpdatePosition(int position) { + if (position >= 0 && position != old_position_) { + masm()->positions_recorder()->RecordPosition(position); + old_position_ = position; + } +} + + static const char* LabelType(LLabel* label) { if (label->is_loop_header()) return " (loop header)"; if (label->is_osr_entry()) return " (OSR entry)"; diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index 59d4ba4ac7..19962a93fd 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -66,7 +66,8 @@ class LCodeGen BASE_EMBEDDED { frame_is_built_(false), safepoints_(info->zone()), resolver_(this), - expected_safepoint_kind_(Safepoint::kSimple) { + expected_safepoint_kind_(Safepoint::kSimple), + old_position_(RelocInfo::kNoPosition) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); } @@ -318,6 +319,7 @@ class LCodeGen BASE_EMBEDDED { int arguments, Safepoint::DeoptMode mode); void RecordPosition(int position); + void RecordAndUpdatePosition(int position); static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); @@ -420,6 +422,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::Kind expected_safepoint_kind_; + int old_position_; + class PushSafepointRegistersScope BASE_EMBEDDED { public: PushSafepointRegistersScope(LCodeGen* codegen, diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 0d22bc9141..725a34e0f7 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -355,6 +355,8 @@ bool LCodeGen::GenerateBody() { if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); + RecordAndUpdatePosition(instr->position()); + instr->CompileToNative(this); if (!CpuFeatures::IsSupported(SSE2)) { @@ -422,6 +424,10 @@ bool LCodeGen::GenerateDeferredCode() { if (deferred_.length() > 0) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { LDeferredCode* code = deferred_[i]; + + int pos = instructions_->at(code->instruction_index())->position(); + RecordAndUpdatePosition(pos); + Comment(";;; <@%d,#%d> " "-------------------- Deferred %s --------------------", code->instruction_index(), @@ -1188,6 +1194,14 @@ void LCodeGen::RecordPosition(int position) { } +void LCodeGen::RecordAndUpdatePosition(int position) { + if (position >= 0 && position != old_position_) { + masm()->positions_recorder()->RecordPosition(position); + old_position_ = position; + } +} + + static const char* LabelType(LLabel* label) { if (label->is_loop_header()) return " (loop header)"; if (label->is_osr_entry()) return " (OSR entry)"; diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 92ba8a1a4f..264f22b683 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -71,7 +71,8 @@ class LCodeGen BASE_EMBEDDED { x87_stack_depth_(0), safepoints_(info->zone()), resolver_(this), - expected_safepoint_kind_(Safepoint::kSimple) { + expected_safepoint_kind_(Safepoint::kSimple), + old_position_(RelocInfo::kNoPosition) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); } @@ -322,6 +323,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::DeoptMode mode); void RecordPosition(int position); + void RecordAndUpdatePosition(int position); + static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); template @@ -451,6 +454,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::Kind expected_safepoint_kind_; + int old_position_; + class PushSafepointRegistersScope BASE_EMBEDDED { public: explicit PushSafepointRegistersScope(LCodeGen* codegen) diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index ef3f64df61..492327439b 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -940,6 +940,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { } #endif + instr->set_position(position_); if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 15c043b863..50084f65c5 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -209,7 +209,10 @@ class LInstruction: public ZoneObject { LInstruction() : environment_(NULL), hydrogen_value_(NULL), - is_call_(false) { } + bit_field_(IsCallBits::encode(false)) { + set_position(RelocInfo::kNoPosition); + } + virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; @@ -248,19 +251,28 @@ class LInstruction: public ZoneObject { LPointerMap* pointer_map() const { return pointer_map_.get(); } bool HasPointerMap() const { return pointer_map_.is_set(); } + // The 31 bits PositionBits is used to store the int position value. And the + // position value may be RelocInfo::kNoPosition (-1). The accessor always + // +1/-1 so that the encoded value of position in bit_field_ is always >= 0 + // and can fit into the 31 bits PositionBits. + void set_position(int pos) { + bit_field_ = PositionBits::update(bit_field_, pos + 1); + } + int position() { return PositionBits::decode(bit_field_) - 1; } void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } - void MarkAsCall() { is_call_ = true; } + void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } + bool IsCall() const { return IsCallBits::decode(bit_field_); } // Interface to the register allocator and iterators. - bool ClobbersTemps() const { return is_call_; } - bool ClobbersRegisters() const { return is_call_; } + bool ClobbersTemps() const { return IsCall(); } + bool ClobbersRegisters() const { return IsCall(); } virtual bool ClobbersDoubleRegisters() const { - return is_call_ || + return IsCall() || (!CpuFeatures::IsSupported(SSE2) && // We only have rudimentary X87Stack tracking, thus in general // cannot handle deoptimization nor phi-nodes. @@ -293,10 +305,13 @@ class LInstruction: public ZoneObject { virtual int TempCount() = 0; virtual LOperand* TempAt(int i) = 0; + class IsCallBits: public BitField {}; + class PositionBits: public BitField {}; + LEnvironment* environment_; SetOncePointer pointer_map_; HValue* hydrogen_value_; - bool is_call_; + int bit_field_; }; diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index a814318f7c..8cbfec2076 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -278,6 +278,8 @@ bool LCodeGen::GenerateBody() { instr->Mnemonic()); } + RecordAndUpdatePosition(instr->position()); + instr->CompileToNative(this); } EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); @@ -331,6 +333,10 @@ bool LCodeGen::GenerateDeferredCode() { if (deferred_.length() > 0) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { LDeferredCode* code = deferred_[i]; + + int pos = instructions_->at(code->instruction_index())->position(); + RecordAndUpdatePosition(pos); + Comment(";;; <@%d,#%d> " "-------------------- Deferred %s --------------------", code->instruction_index(), @@ -879,6 +885,14 @@ void LCodeGen::RecordPosition(int position) { } +void LCodeGen::RecordAndUpdatePosition(int position) { + if (position >= 0 && position != old_position_) { + masm()->positions_recorder()->RecordPosition(position); + old_position_ = position; + } +} + + static const char* LabelType(LLabel* label) { if (label->is_loop_header()) return " (loop header)"; if (label->is_osr_entry()) return " (OSR entry)"; diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 11c9ec3792..1b680d4465 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -67,7 +67,8 @@ class LCodeGen BASE_EMBEDDED { frame_is_built_(false), safepoints_(info->zone()), resolver_(this), - expected_safepoint_kind_(Safepoint::kSimple) { + expected_safepoint_kind_(Safepoint::kSimple), + old_position_(RelocInfo::kNoPosition) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); } @@ -282,6 +283,7 @@ class LCodeGen BASE_EMBEDDED { int arguments, Safepoint::DeoptMode mode); void RecordPosition(int position); + void RecordAndUpdatePosition(int position); static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); @@ -384,6 +386,8 @@ class LCodeGen BASE_EMBEDDED { Safepoint::Kind expected_safepoint_kind_; + int old_position_; + class PushSafepointRegistersScope BASE_EMBEDDED { public: explicit PushSafepointRegistersScope(LCodeGen* codegen) diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 4b2ffbe212..2a9511bb5a 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -884,6 +884,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { } #endif + instr->set_position(position_); if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index b2fb1daf78..c83c34dcd5 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -205,9 +205,11 @@ class LCodeGen; class LInstruction: public ZoneObject { public: LInstruction() - : environment_(NULL), - hydrogen_value_(NULL), - is_call_(false) { } + : environment_(NULL), + hydrogen_value_(NULL), + bit_field_(IsCallBits::encode(false)) { + set_position(RelocInfo::kNoPosition); + } virtual ~LInstruction() { } @@ -247,20 +249,30 @@ class LInstruction: public ZoneObject { LPointerMap* pointer_map() const { return pointer_map_.get(); } bool HasPointerMap() const { return pointer_map_.is_set(); } + // The 31 bits PositionBits is used to store the int position value. And the + // position value may be RelocInfo::kNoPosition (-1). The accessor always + // +1/-1 so that the encoded value of position in bit_field_ is always >= 0 + // and can fit into the 31 bits PositionBits. + void set_position(int pos) { + bit_field_ = PositionBits::update(bit_field_, pos + 1); + } + int position() { return PositionBits::decode(bit_field_) - 1; } + void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } - void MarkAsCall() { is_call_ = true; } + void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } + bool IsCall() const { return IsCallBits::decode(bit_field_); } // Interface to the register allocator and iterators. - bool ClobbersTemps() const { return is_call_; } - bool ClobbersRegisters() const { return is_call_; } - bool ClobbersDoubleRegisters() const { return is_call_; } + bool ClobbersTemps() const { return IsCall(); } + bool ClobbersRegisters() const { return IsCall(); } + bool ClobbersDoubleRegisters() const { return IsCall(); } virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } // Interface to the register allocator and iterators. - bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsCall() const { return IsCall(); } virtual bool HasResult() const = 0; virtual LOperand* result() const = 0; @@ -284,10 +296,13 @@ class LInstruction: public ZoneObject { virtual int TempCount() = 0; virtual LOperand* TempAt(int i) = 0; + class IsCallBits: public BitField {}; + class PositionBits: public BitField {}; + LEnvironment* environment_; SetOncePointer pointer_map_; HValue* hydrogen_value_; - bool is_call_; + int bit_field_; };