Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc
index c757557..26aebca 100644
--- a/src/compiler/instruction.cc
+++ b/src/compiler/instruction.cc
@@ -127,12 +127,12 @@
LocationOperand allocated = LocationOperand::cast(op);
if (op.IsStackSlot()) {
os << "[stack:" << LocationOperand::cast(op).index();
- } else if (op.IsDoubleStackSlot()) {
- os << "[double_stack:" << LocationOperand::cast(op).index();
+ } else if (op.IsFPStackSlot()) {
+ os << "[fp_stack:" << LocationOperand::cast(op).index();
} else if (op.IsRegister()) {
os << "[" << LocationOperand::cast(op).GetRegister().ToString() << "|R";
} else {
- DCHECK(op.IsDoubleRegister());
+ DCHECK(op.IsFPRegister());
os << "[" << LocationOperand::cast(op).GetDoubleRegister().ToString()
<< "|R";
}
@@ -251,17 +251,16 @@
DoubleRegister::from_code(index).IsAllocatable());
}
-
Instruction::Instruction(InstructionCode opcode)
: opcode_(opcode),
bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
TempCountField::encode(0) | IsCallField::encode(false)),
- reference_map_(nullptr) {
+ reference_map_(nullptr),
+ block_(nullptr) {
parallel_moves_[0] = nullptr;
parallel_moves_[1] = nullptr;
}
-
Instruction::Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, size_t temp_count,
@@ -271,7 +270,8 @@
InputCountField::encode(input_count) |
TempCountField::encode(temp_count) |
IsCallField::encode(false)),
- reference_map_(nullptr) {
+ reference_map_(nullptr),
+ block_(nullptr) {
parallel_moves_[0] = nullptr;
parallel_moves_[1] = nullptr;
size_t offset = 0;
@@ -335,7 +335,7 @@
void ReferenceMap::RecordReference(const AllocatedOperand& op) {
// Do not record arguments as pointers.
if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return;
- DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot());
+ DCHECK(!op.IsFPRegister() && !op.IsFPStackSlot());
reference_operands_.push_back(op);
}
@@ -504,6 +504,27 @@
Constant::Constant(int32_t v) : type_(kInt32), value_(v) {}
+Constant::Constant(RelocatablePtrConstantInfo info) {
+ if (info.type() == RelocatablePtrConstantInfo::kInt32) {
+ type_ = kInt32;
+ } else if (info.type() == RelocatablePtrConstantInfo::kInt64) {
+ type_ = kInt64;
+ } else {
+ UNREACHABLE();
+ }
+ value_ = info.value();
+ rmode_ = info.rmode();
+}
+
+Handle<HeapObject> Constant::ToHeapObject() const {
+ DCHECK_EQ(kHeapObject, type());
+ Handle<HeapObject> value(
+ bit_cast<HeapObject**>(static_cast<intptr_t>(value_)));
+ if (value->IsConsString()) {
+ value = String::Flatten(Handle<String>::cast(value), TENURED);
+ }
+ return value;
+}
std::ostream& operator<<(std::ostream& os, const Constant& constant) {
switch (constant.type()) {
@@ -603,7 +624,6 @@
return instr_block;
}
-
InstructionBlocks* InstructionSequence::InstructionBlocksFor(
Zone* zone, const Schedule* schedule) {
InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
@@ -620,7 +640,7 @@
return blocks;
}
-void InstructionSequence::ValidateEdgeSplitForm() {
+void InstructionSequence::ValidateEdgeSplitForm() const {
// Validate blocks are in edge-split form: no block with multiple successors
// has an edge to a block (== a successor) with more than one predecessors.
for (const InstructionBlock* block : instruction_blocks()) {
@@ -635,7 +655,7 @@
}
}
-void InstructionSequence::ValidateDeferredBlockExitPaths() {
+void InstructionSequence::ValidateDeferredBlockExitPaths() const {
// A deferred block with more than one successor must have all its successors
// deferred.
for (const InstructionBlock* block : instruction_blocks()) {
@@ -646,7 +666,21 @@
}
}
-void InstructionSequence::ValidateSSA() {
+void InstructionSequence::ValidateDeferredBlockEntryPaths() const {
+ // If a deferred block has multiple predecessors, they have to
+ // all be deferred. Otherwise, we can run into a situation where a range
+ // that spills only in deferred blocks inserts its spill in the block, but
+ // other ranges need moves inserted by ResolveControlFlow in the predecessors,
+ // which may clobber the register of this range.
+ for (const InstructionBlock* block : instruction_blocks()) {
+ if (!block->IsDeferred() || block->PredecessorCount() <= 1) continue;
+ for (RpoNumber predecessor_id : block->predecessors()) {
+ CHECK(InstructionBlockAt(predecessor_id)->IsDeferred());
+ }
+ }
+}
+
+void InstructionSequence::ValidateSSA() const {
// TODO(mtrofin): We could use a local zone here instead.
BitVector definitions(VirtualRegisterCount(), zone());
for (const Instruction* instruction : *this) {
@@ -675,7 +709,6 @@
}
}
-
InstructionSequence::InstructionSequence(Isolate* isolate,
Zone* instruction_zone,
InstructionBlocks* instruction_blocks)
@@ -683,7 +716,6 @@
zone_(instruction_zone),
instruction_blocks_(instruction_blocks),
source_positions_(zone()),
- block_starts_(zone()),
constants_(ConstantMap::key_compare(),
ConstantMap::allocator_type(zone())),
immediates_(zone()),
@@ -691,10 +723,8 @@
next_virtual_register_(0),
reference_maps_(zone()),
representations_(zone()),
- deoptimization_entries_(zone()) {
- block_starts_.reserve(instruction_blocks_->size());
-}
-
+ deoptimization_entries_(zone()),
+ current_block_(nullptr) {}
int InstructionSequence::NextVirtualRegister() {
int virtual_register = next_virtual_register_++;
@@ -710,28 +740,31 @@
void InstructionSequence::StartBlock(RpoNumber rpo) {
- DCHECK(block_starts_.size() == rpo.ToSize());
- InstructionBlock* block = InstructionBlockAt(rpo);
+ DCHECK_NULL(current_block_);
+ current_block_ = InstructionBlockAt(rpo);
int code_start = static_cast<int>(instructions_.size());
- block->set_code_start(code_start);
- block_starts_.push_back(code_start);
+ current_block_->set_code_start(code_start);
}
void InstructionSequence::EndBlock(RpoNumber rpo) {
int end = static_cast<int>(instructions_.size());
- InstructionBlock* block = InstructionBlockAt(rpo);
- if (block->code_start() == end) { // Empty block. Insert a nop.
+ DCHECK_EQ(current_block_->rpo_number(), rpo);
+ if (current_block_->code_start() == end) { // Empty block. Insert a nop.
AddInstruction(Instruction::New(zone(), kArchNop));
end = static_cast<int>(instructions_.size());
}
- DCHECK(block->code_start() >= 0 && block->code_start() < end);
- block->set_code_end(end);
+ DCHECK(current_block_->code_start() >= 0 &&
+ current_block_->code_start() < end);
+ current_block_->set_code_end(end);
+ current_block_ = nullptr;
}
int InstructionSequence::AddInstruction(Instruction* instr) {
+ DCHECK_NOT_NULL(current_block_);
int index = static_cast<int>(instructions_.size());
+ instr->set_block(current_block_);
instructions_.push_back(instr);
if (instr->NeedsReferenceMap()) {
DCHECK(instr->reference_map() == nullptr);
@@ -746,18 +779,7 @@
InstructionBlock* InstructionSequence::GetInstructionBlock(
int instruction_index) const {
- DCHECK(instruction_blocks_->size() == block_starts_.size());
- auto begin = block_starts_.begin();
- auto end = std::lower_bound(begin, block_starts_.end(), instruction_index);
- // Post condition of std::lower_bound:
- DCHECK(end == block_starts_.end() || *end >= instruction_index);
- if (end == block_starts_.end() || *end > instruction_index) --end;
- DCHECK(*end <= instruction_index);
- size_t index = std::distance(begin, end);
- InstructionBlock* block = instruction_blocks_->at(index);
- DCHECK(block->code_start() <= instruction_index &&
- instruction_index < block->code_end());
- return block;
+ return instructions()[instruction_index]->block();
}