diff options
Diffstat (limited to 'deps/v8/src/assembler.cc')
-rw-r--r-- | deps/v8/src/assembler.cc | 147 |
1 files changed, 118 insertions, 29 deletions
diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc index c73b470c28..f4299ed717 100644 --- a/deps/v8/src/assembler.cc +++ b/deps/v8/src/assembler.cc @@ -65,6 +65,8 @@ #include "src/arm64/assembler-arm64-inl.h" // NOLINT #elif V8_TARGET_ARCH_ARM #include "src/arm/assembler-arm-inl.h" // NOLINT +#elif V8_TARGET_ARCH_PPC +#include "src/ppc/assembler-ppc-inl.h" // NOLINT #elif V8_TARGET_ARCH_MIPS #include "src/mips/assembler-mips-inl.h" // NOLINT #elif V8_TARGET_ARCH_MIPS64 @@ -85,6 +87,8 @@ #include "src/arm64/regexp-macro-assembler-arm64.h" // NOLINT #elif V8_TARGET_ARCH_ARM #include "src/arm/regexp-macro-assembler-arm.h" // NOLINT +#elif V8_TARGET_ARCH_PPC +#include "src/ppc/regexp-macro-assembler-ppc.h" // NOLINT #elif V8_TARGET_ARCH_MIPS #include "src/mips/regexp-macro-assembler-mips.h" // NOLINT #elif V8_TARGET_ARCH_MIPS64 @@ -107,7 +111,6 @@ double min_int; double one_half; double minus_one_half; double negative_infinity; -double canonical_non_hole_nan; double the_hole_nan; double uint32_bias; }; @@ -253,6 +256,7 @@ int Label::pos() const { // position: 01 // statement_position: 10 // comment: 11 (not used in short_data_record) +// deopt_reason: 11 (not used in long_data_record) // // Long record format: // 4-bit middle_tag: @@ -325,6 +329,10 @@ const int kNonstatementPositionTag = 1; const int kStatementPositionTag = 2; const int kCommentTag = 3; +// Reuse the same value for deopt reason tag in short record format. +// It is possible because we use kCommentTag only for the long record format. +const int kDeoptReasonTag = 3; + const int kPoolExtraTag = kPCJumpExtraTag - 2; const int kConstPoolTag = 0; const int kVeneerPoolTag = 1; @@ -407,7 +415,38 @@ void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { } +void RelocInfoWriter::WritePosition(int pc_delta, int pos_delta, + RelocInfo::Mode rmode) { + int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag + : kStatementPositionTag; + // Check if delta is small enough to fit in a tagged byte. + if (is_intn(pos_delta, kSmallDataBits)) { + WriteTaggedPC(pc_delta, kLocatableTag); + WriteTaggedData(pos_delta, pos_type_tag); + } else { + // Otherwise, use costly encoding. + WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); + WriteExtraTaggedIntData(pos_delta, pos_type_tag); + } +} + + +void RelocInfoWriter::FlushPosition() { + if (!next_position_candidate_flushed_) { + WritePosition(next_position_candidate_pc_delta_, + next_position_candidate_pos_delta_, RelocInfo::POSITION); + next_position_candidate_pos_delta_ = 0; + next_position_candidate_pc_delta_ = 0; + next_position_candidate_flushed_ = true; + } +} + + void RelocInfoWriter::Write(const RelocInfo* rinfo) { + RelocInfo::Mode rmode = rinfo->rmode(); + if (rmode != RelocInfo::POSITION) { + FlushPosition(); + } #ifdef DEBUG byte* begin_pos = pos_; #endif @@ -417,7 +456,6 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { <= kMaxStandardNonCompactModes); // Use unsigned delta-encoding for pc. uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); - RelocInfo::Mode rmode = rinfo->rmode(); // The two most common modes are given small tags, and usually fit in a byte. if (rmode == RelocInfo::EMBEDDED_OBJECT) { @@ -439,20 +477,26 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { WriteExtraTaggedIntData(id_delta, kCodeWithIdTag); } last_id_ = static_cast<int>(rinfo->data()); + } else if (rmode == RelocInfo::DEOPT_REASON) { + DCHECK(rinfo->data() < (1 << kSmallDataBits)); + WriteTaggedPC(pc_delta, kLocatableTag); + WriteTaggedData(rinfo->data(), kDeoptReasonTag); } else if (RelocInfo::IsPosition(rmode)) { // Use signed delta-encoding for position. DCHECK(static_cast<int>(rinfo->data()) == rinfo->data()); int pos_delta = static_cast<int>(rinfo->data()) - last_position_; - int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag - : kStatementPositionTag; - // Check if delta is small enough to fit in a tagged byte. - if (is_intn(pos_delta, kSmallDataBits)) { - WriteTaggedPC(pc_delta, kLocatableTag); - WriteTaggedData(pos_delta, pos_type_tag); + if (rmode == RelocInfo::STATEMENT_POSITION) { + WritePosition(pc_delta, pos_delta, rmode); } else { - // Otherwise, use costly encoding. - WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); - WriteExtraTaggedIntData(pos_delta, pos_type_tag); + DCHECK(rmode == RelocInfo::POSITION); + if (pc_delta != 0 || last_mode_ != RelocInfo::POSITION) { + FlushPosition(); + next_position_candidate_pc_delta_ = pc_delta; + next_position_candidate_pos_delta_ = pos_delta; + } else { + next_position_candidate_pos_delta_ += pos_delta; + } + next_position_candidate_flushed_ = false; } last_position_ = static_cast<int>(rinfo->data()); } else if (RelocInfo::IsComment(rmode)) { @@ -470,10 +514,11 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM; // For all other modes we simply use the mode as the extra tag. // None of these modes need a data component. - DCHECK(saved_mode < kPCJumpExtraTag && saved_mode < kDataJumpExtraTag); + DCHECK(saved_mode < kPoolExtraTag); WriteExtraTaggedPC(pc_delta, saved_mode); } last_pc_ = rinfo->pc(); + last_mode_ = rmode; #ifdef DEBUG DCHECK(begin_pos - pos_ <= kMaxSize); #endif @@ -580,6 +625,12 @@ inline void RelocIterator::ReadTaggedPosition() { } +inline void RelocIterator::ReadTaggedData() { + uint8_t unsigned_b = *pos_; + rinfo_.data_ = unsigned_b >> kTagBits; +} + + static inline RelocInfo::Mode GetPositionModeFromTag(int tag) { DCHECK(tag == kNonstatementPositionTag || tag == kStatementPositionTag); @@ -613,9 +664,10 @@ void RelocIterator::next() { ReadTaggedId(); return; } + } else if (locatable_tag == kDeoptReasonTag) { + ReadTaggedData(); + if (SetMode(RelocInfo::DEOPT_REASON)) return; } else { - // Compact encoding is never used for comments, - // so it must be a position. DCHECK(locatable_tag == kNonstatementPositionTag || locatable_tag == kStatementPositionTag); if (mode_mask_ & RelocInfo::kPositionMask) { @@ -780,6 +832,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { return "external reference"; case RelocInfo::INTERNAL_REFERENCE: return "internal reference"; + case RelocInfo::DEOPT_REASON: + return "deopt reason"; case RelocInfo::CONST_POOL: return "constant pool"; case RelocInfo::VENEER_POOL: @@ -800,6 +854,9 @@ void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT os << static_cast<const void*>(pc_) << " " << RelocModeName(rmode_); if (IsComment(rmode_)) { os << " (" << reinterpret_cast<char*>(data_) << ")"; + } else if (rmode_ == DEOPT_REASON) { + os << " (" << Deoptimizer::GetDeoptReason( + static_cast<Deoptimizer::DeoptReason>(data_)) << ")"; } else if (rmode_ == EMBEDDED_OBJECT) { os << " (" << Brief(target_object()) << ")"; } else if (rmode_ == EXTERNAL_REFERENCE) { @@ -860,6 +917,7 @@ void RelocInfo::Verify(Isolate* isolate) { case STATEMENT_POSITION: case EXTERNAL_REFERENCE: case INTERNAL_REFERENCE: + case DEOPT_REASON: case CONST_POOL: case VENEER_POOL: case DEBUG_BREAK_SLOT: @@ -884,7 +942,6 @@ void ExternalReference::SetUp() { double_constants.min_int = kMinInt; double_constants.one_half = 0.5; double_constants.minus_one_half = -0.5; - double_constants.canonical_non_hole_nan = base::OS::nan_value(); double_constants.the_hole_nan = bit_cast<double>(kHoleNanInt64); double_constants.negative_infinity = -V8_INFINITY; double_constants.uint32_bias = @@ -1242,12 +1299,6 @@ ExternalReference ExternalReference::address_of_negative_infinity() { } -ExternalReference ExternalReference::address_of_canonical_non_hole_nan() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan)); -} - - ExternalReference ExternalReference::address_of_the_hole_nan() { return ExternalReference( reinterpret_cast<void*>(&double_constants.the_hole_nan)); @@ -1297,6 +1348,8 @@ ExternalReference ExternalReference::re_check_stack_guard_state( function = FUNCTION_ADDR(RegExpMacroAssemblerARM64::CheckStackGuardState); #elif V8_TARGET_ARCH_ARM function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState); +#elif V8_TARGET_ARCH_PPC + function = FUNCTION_ADDR(RegExpMacroAssemblerPPC::CheckStackGuardState); #elif V8_TARGET_ARCH_MIPS function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState); #elif V8_TARGET_ARCH_MIPS64 @@ -1443,15 +1496,18 @@ double power_double_int(double x, int y) { double power_double_double(double x, double y) { -#if defined(__MINGW64_VERSION_MAJOR) && \ - (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) - // MinGW64 has a custom implementation for pow. This handles certain +#if (defined(__MINGW64_VERSION_MAJOR) && \ + (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)) || \ + defined(V8_OS_AIX) + // MinGW64 and AIX have a custom implementation for pow. This handles certain // special cases that are different. - if ((x == 0.0 || std::isinf(x)) && std::isfinite(y)) { + if ((x == 0.0 || std::isinf(x)) && y != 0.0 && std::isfinite(y)) { double f; - if (std::modf(y, &f) != 0.0) { - return ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0; - } + double result = ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0; + /* retain sign if odd integer exponent */ + return ((std::modf(y, &f) == 0.0) && (static_cast<int64_t>(y) & 1)) + ? copysign(result, x) + : result; } if (x == 2.0) { @@ -1465,7 +1521,7 @@ double power_double_double(double x, double y) { // The checks for special cases can be dropped in ia32 because it has already // been done in generated code before bailing out here. if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) { - return base::OS::nan_value(); + return std::numeric_limits<double>::quiet_NaN(); } return std::pow(x, y); } @@ -1596,4 +1652,37 @@ bool PositionsRecorder::WriteRecordedPositions() { return written; } + +// Platform specific but identical code for all the platforms. + + +void Assembler::RecordDeoptReason(const int reason, const int raw_position) { + if (FLAG_trace_deopt || isolate()->cpu_profiler()->is_profiling()) { + EnsureSpace ensure_space(this); + RecordRelocInfo(RelocInfo::POSITION, raw_position); + RecordRelocInfo(RelocInfo::DEOPT_REASON, reason); + } +} + + +void Assembler::RecordComment(const char* msg) { + if (FLAG_code_comments) { + EnsureSpace ensure_space(this); + RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); + } +} + + +void Assembler::RecordJSReturn() { + positions_recorder()->WriteRecordedPositions(); + EnsureSpace ensure_space(this); + RecordRelocInfo(RelocInfo::JS_RETURN); +} + + +void Assembler::RecordDebugBreakSlot() { + positions_recorder()->WriteRecordedPositions(); + EnsureSpace ensure_space(this); + RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); +} } } // namespace v8::internal |