Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/mips64/assembler-mips64-inl.h b/src/mips64/assembler-mips64-inl.h
index 76dd801..09436ed 100644
--- a/src/mips64/assembler-mips64-inl.h
+++ b/src/mips64/assembler-mips64-inl.h
@@ -40,7 +40,7 @@
#include "src/mips64/assembler-mips64.h"
#include "src/assembler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
namespace v8 {
@@ -84,45 +84,15 @@
}
-int Register::NumAllocatableRegisters() {
- return kMaxNumAllocatableRegisters;
-}
-
-
-int DoubleRegister::NumRegisters() {
- return FPURegister::kMaxNumRegisters;
-}
-
-
-int DoubleRegister::NumAllocatableRegisters() {
- return FPURegister::kMaxNumAllocatableRegisters;
-}
-
-
-int DoubleRegister::NumAllocatableAliasedRegisters() {
- return NumAllocatableRegisters();
-}
-
-
-int FPURegister::ToAllocationIndex(FPURegister reg) {
- DCHECK(reg.code() % 2 == 0);
- DCHECK(reg.code() / 2 < kMaxNumAllocatableRegisters);
- DCHECK(reg.is_valid());
- DCHECK(!reg.is(kDoubleRegZero));
- DCHECK(!reg.is(kLithiumScratchDouble));
- return (reg.code() / 2);
-}
-
-
// -----------------------------------------------------------------------------
// RelocInfo.
-void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
- if (IsInternalReference(rmode_)) {
+void RelocInfo::apply(intptr_t delta) {
+ if (IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)) {
// Absolute code pointer inside code object moves with the code object.
byte* p = reinterpret_cast<byte*>(pc_);
- int count = Assembler::RelocateInternalReference(p, delta);
- CpuFeatures::FlushICache(p, count * sizeof(uint32_t));
+ int count = Assembler::RelocateInternalReference(rmode_, p, delta);
+ Assembler::FlushICache(isolate_, p, count * sizeof(uint32_t));
}
}
@@ -174,7 +144,8 @@
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
- Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
+ Assembler::set_target_address_at(isolate_, pc_, host_, target,
+ icache_flush_mode);
if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL && IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
@@ -189,8 +160,33 @@
}
-Address Assembler::break_address_from_return_address(Address pc) {
- return pc - Assembler::kPatchDebugBreakSlotReturnOffset;
+void Assembler::set_target_internal_reference_encoded_at(Address pc,
+ Address target) {
+ // Encoded internal references are j/jal instructions.
+ Instr instr = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
+
+ uint64_t imm28 =
+ (reinterpret_cast<uint64_t>(target) & static_cast<uint64_t>(kImm28Mask));
+
+ instr &= ~kImm26Mask;
+ uint64_t imm26 = imm28 >> 2;
+ DCHECK(is_uint26(imm26));
+
+ instr_at_put(pc, instr | (imm26 & kImm26Mask));
+ // Currently used only by deserializer, and all code will be flushed
+ // after complete deserialization, no need to flush on each reference.
+}
+
+
+void Assembler::deserialization_set_target_internal_reference_at(
+ Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) {
+ if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
+ DCHECK(IsJ(instr_at(pc)));
+ set_target_internal_reference_encoded_at(pc, target);
+ } else {
+ DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
+ Memory::Address_at(pc) = target;
+ }
}
@@ -211,7 +207,7 @@
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- Assembler::set_target_address_at(pc_, host_,
+ Assembler::set_target_address_at(isolate_, pc_, host_,
reinterpret_cast<Address>(target),
icache_flush_mode);
if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
@@ -223,12 +219,34 @@
}
-Address RelocInfo::target_reference() {
+Address RelocInfo::target_external_reference() {
DCHECK(rmode_ == EXTERNAL_REFERENCE);
return Assembler::target_address_at(pc_, host_);
}
+Address RelocInfo::target_internal_reference() {
+ if (rmode_ == INTERNAL_REFERENCE) {
+ return Memory::Address_at(pc_);
+ } else {
+ // Encoded internal references are j/jal instructions.
+ DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED);
+ Instr instr = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
+ instr &= kImm26Mask;
+ uint64_t imm28 = instr << 2;
+ uint64_t segment =
+ (reinterpret_cast<uint64_t>(pc_) & ~static_cast<uint64_t>(kImm28Mask));
+ return reinterpret_cast<Address>(segment | imm28);
+ }
+}
+
+
+Address RelocInfo::target_internal_reference_address() {
+ DCHECK(rmode_ == INTERNAL_REFERENCE || rmode_ == INTERNAL_REFERENCE_ENCODED);
+ return reinterpret_cast<Address>(pc_);
+}
+
+
Address RelocInfo::target_runtime_entry(Assembler* origin) {
DCHECK(IsRuntimeEntry(rmode_));
return target_address();
@@ -291,29 +309,24 @@
void RelocInfo::set_code_age_stub(Code* stub,
ICacheFlushMode icache_flush_mode) {
DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- Assembler::set_target_address_at(pc_ + Assembler::kInstrSize,
- host_,
+ Assembler::set_target_address_at(isolate_, pc_ + Assembler::kInstrSize, host_,
stub->instruction_start());
}
-Address RelocInfo::call_address() {
- DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
- (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
- // The pc_ offset of 0 assumes mips patched return sequence per
- // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
- // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
+Address RelocInfo::debug_call_address() {
+ // The pc_ offset of 0 assumes patched debug break slot or return
+ // sequence.
+ DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
return Assembler::target_address_at(pc_, host_);
}
-void RelocInfo::set_call_address(Address target) {
- DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
- (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
- // The pc_ offset of 0 assumes mips patched return sequence per
- // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
- // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
- Assembler::set_target_address_at(pc_, host_, target);
+void RelocInfo::set_debug_call_address(Address target) {
+ DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
+ // The pc_ offset of 0 assumes patched debug break slot or return
+ // sequence.
+ Assembler::set_target_address_at(isolate_, pc_, host_, target);
if (host() != NULL) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
@@ -322,29 +335,17 @@
}
-Object* RelocInfo::call_object() {
- return *call_object_address();
-}
-
-
-Object** RelocInfo::call_object_address() {
- DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
- (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
- return reinterpret_cast<Object**>(pc_ + 6 * Assembler::kInstrSize);
-}
-
-
-void RelocInfo::set_call_object(Object* target) {
- *call_object_address() = target;
-}
-
-
void RelocInfo::WipeOut() {
- DCHECK(IsEmbeddedObject(rmode_) ||
- IsCodeTarget(rmode_) ||
- IsRuntimeEntry(rmode_) ||
- IsExternalReference(rmode_));
- Assembler::set_target_address_at(pc_, host_, NULL);
+ DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
+ IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
+ IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_));
+ if (IsInternalReference(rmode_)) {
+ Memory::Address_at(pc_) = NULL;
+ } else if (IsInternalReferenceEncoded(rmode_)) {
+ Assembler::set_target_internal_reference_encoded_at(pc_, nullptr);
+ } else {
+ Assembler::set_target_address_at(isolate_, pc_, host_, NULL);
+ }
}
@@ -380,13 +381,13 @@
visitor->VisitCell(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
+ } else if (mode == RelocInfo::INTERNAL_REFERENCE ||
+ mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
+ visitor->VisitInternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
- } else if (((RelocInfo::IsJSReturn(mode) &&
- IsPatchedReturnSequence()) ||
- (RelocInfo::IsDebugBreakSlot(mode) &&
- IsPatchedDebugBreakSlotSequence())) &&
- isolate->debug()->has_break_points()) {
+ } else if (RelocInfo::IsDebugBreakSlot(mode) &&
+ IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
@@ -405,13 +406,13 @@
StaticVisitor::VisitCell(heap, this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
StaticVisitor::VisitExternalReference(this);
+ } else if (mode == RelocInfo::INTERNAL_REFERENCE ||
+ mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
+ StaticVisitor::VisitInternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
- } else if (heap->isolate()->debug()->has_break_points() &&
- ((RelocInfo::IsJSReturn(mode) &&
- IsPatchedReturnSequence()) ||
- (RelocInfo::IsDebugBreakSlot(mode) &&
- IsPatchedDebugBreakSlotSequence()))) {
+ } else if (RelocInfo::IsDebugBreakSlot(mode) &&
+ IsPatchedDebugBreakSlotSequence()) {
StaticVisitor::VisitDebugTarget(heap, this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
@@ -430,33 +431,70 @@
}
-void Assembler::CheckTrampolinePoolQuick() {
- if (pc_offset() >= next_buffer_check_) {
+void Assembler::CheckTrampolinePoolQuick(int extra_instructions) {
+ if (pc_offset() >= next_buffer_check_ - extra_instructions * kInstrSize) {
CheckTrampolinePool();
}
}
-void Assembler::emit(Instr x) {
+void Assembler::CheckForEmitInForbiddenSlot() {
if (!is_buffer_growth_blocked()) {
CheckBuffer();
}
+ if (IsPrevInstrCompactBranch()) {
+ // Nop instruction to preceed a CTI in forbidden slot:
+ Instr nop = SPECIAL | SLL;
+ *reinterpret_cast<Instr*>(pc_) = nop;
+ pc_ += kInstrSize;
+
+ ClearCompactBranchState();
+ }
+}
+
+
+void Assembler::EmitHelper(Instr x, CompactBranchType is_compact_branch) {
+ if (IsPrevInstrCompactBranch()) {
+ if (Instruction::IsForbiddenAfterBranchInstr(x)) {
+ // Nop instruction to preceed a CTI in forbidden slot:
+ Instr nop = SPECIAL | SLL;
+ *reinterpret_cast<Instr*>(pc_) = nop;
+ pc_ += kInstrSize;
+ }
+ ClearCompactBranchState();
+ }
*reinterpret_cast<Instr*>(pc_) = x;
pc_ += kInstrSize;
+ if (is_compact_branch == CompactBranchType::COMPACT_BRANCH) {
+ EmittedCompactBranchInstruction();
+ }
CheckTrampolinePoolQuick();
}
-void Assembler::emit(uint64_t x) {
+template <typename T>
+void Assembler::EmitHelper(T x) {
+ *reinterpret_cast<T*>(pc_) = x;
+ pc_ += sizeof(x);
+ CheckTrampolinePoolQuick();
+}
+
+
+void Assembler::emit(Instr x, CompactBranchType is_compact_branch) {
if (!is_buffer_growth_blocked()) {
CheckBuffer();
}
- *reinterpret_cast<uint64_t*>(pc_) = x;
- pc_ += kInstrSize * 2;
- CheckTrampolinePoolQuick();
+ EmitHelper(x, is_compact_branch);
}
-} } // namespace v8::internal
+void Assembler::emit(uint64_t data) {
+ CheckForEmitInForbiddenSlot();
+ EmitHelper(data);
+}
+
+
+} // namespace internal
+} // namespace v8
#endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_