Upgrade V8 to 8.8.278.14
Bug: 162604069
Bug: 167389063
Test: gts-tradefed run gts-dev --module GtsGmscoreHostTestCases
--test com.google.android.gts.devicepolicy.DeviceOwnerTest#testProxyPacProxyTest
Test: m -j proxy_resolver_v8_unittest && adb sync && adb shell \
/data/nativetest/proxy_resolver_v8_unittest/proxy_resolver_v8_unittest
Merged-In: Ifb09923b9d7f6d8990fb062d7dc0294edf2c098e
Change-Id: Ifb09923b9d7f6d8990fb062d7dc0294edf2c098e
(cherry picked from commit 9580a23bc5b8874a0979001d3595d027cbb68128)
diff --git a/src/compiler/node.cc b/src/compiler/node.cc
index 16dc2db..8525fa0 100644
--- a/src/compiler/node.cc
+++ b/src/compiler/node.cc
@@ -11,7 +11,8 @@
Node::OutOfLineInputs* Node::OutOfLineInputs::New(Zone* zone, int capacity) {
size_t size =
sizeof(OutOfLineInputs) + capacity * (sizeof(Node*) + sizeof(Use));
- intptr_t raw_buffer = reinterpret_cast<intptr_t>(zone->New(size));
+ intptr_t raw_buffer =
+ reinterpret_cast<intptr_t>(zone->Allocate<Node::OutOfLineInputs>(size));
Node::OutOfLineInputs* outline =
reinterpret_cast<OutOfLineInputs*>(raw_buffer + capacity * sizeof(Use));
outline->capacity_ = capacity;
@@ -19,13 +20,14 @@
return outline;
}
-
-void Node::OutOfLineInputs::ExtractFrom(Use* old_use_ptr, Node** old_input_ptr,
- int count) {
+void Node::OutOfLineInputs::ExtractFrom(Use* old_use_ptr,
+ ZoneNodePtr* old_input_ptr, int count) {
+ DCHECK_GE(count, 0);
// Extract the inputs from the old use and input pointers and copy them
// to this out-of-line-storage.
Use* new_use_ptr = reinterpret_cast<Use*>(this) - 1;
- Node** new_input_ptr = inputs_;
+ ZoneNodePtr* new_input_ptr = inputs();
+ CHECK_IMPLIES(count > 0, Use::InputIndexField::is_valid(count - 1));
for (int current = 0; current < count; current++) {
new_use_ptr->bit_field_ =
Use::InputIndexField::encode(current) | Use::InlineField::encode(false);
@@ -48,23 +50,29 @@
this->count_ = count;
}
+// These structs are just type tags for Zone::Allocate<T>(size_t) calls.
+struct NodeWithOutOfLineInputs {};
+struct NodeWithInLineInputs {};
-Node* Node::New(Zone* zone, NodeId id, const Operator* op, int input_count,
- Node* const* inputs, bool has_extensible_inputs) {
- Node** input_ptr;
+template <typename NodePtrT>
+Node* Node::NewImpl(Zone* zone, NodeId id, const Operator* op, int input_count,
+ NodePtrT const* inputs, bool has_extensible_inputs) {
+ // Node uses compressed pointers, so zone must support pointer compression.
+ DCHECK_IMPLIES(kCompressGraphZone, zone->supports_compression());
+ DCHECK_GE(input_count, 0);
+
+ ZoneNodePtr* input_ptr;
Use* use_ptr;
Node* node;
bool is_inline;
-#if DEBUG
// Verify that none of the inputs are {nullptr}.
for (int i = 0; i < input_count; i++) {
if (inputs[i] == nullptr) {
- V8_Fatal(__FILE__, __LINE__, "Node::New() Error: #%d:%s[%d] is nullptr",
- static_cast<int>(id), op->mnemonic(), i);
+ FATAL("Node::New() Error: #%d:%s[%d] is nullptr", static_cast<int>(id),
+ op->mnemonic(), i);
}
}
-#endif
if (input_count > kMaxInlineCapacity) {
// Allocate out-of-line inputs.
@@ -72,37 +80,42 @@
has_extensible_inputs ? input_count + kMaxInlineCapacity : input_count;
OutOfLineInputs* outline = OutOfLineInputs::New(zone, capacity);
- // Allocate node.
- void* node_buffer = zone->New(sizeof(Node));
+ // Allocate node, with space for OutOfLineInputs pointer.
+ void* node_buffer = zone->Allocate<NodeWithOutOfLineInputs>(
+ sizeof(Node) + sizeof(ZoneOutOfLineInputsPtr));
node = new (node_buffer) Node(id, op, kOutlineMarker, 0);
- node->inputs_.outline_ = outline;
+ node->set_outline_inputs(outline);
outline->node_ = node;
outline->count_ = input_count;
- input_ptr = outline->inputs_;
+ input_ptr = outline->inputs();
use_ptr = reinterpret_cast<Use*>(outline);
is_inline = false;
} else {
- // Allocate node with inline inputs.
- int capacity = input_count;
+ // Allocate node with inline inputs. Capacity must be at least 1 so that
+ // an OutOfLineInputs pointer can be stored when inputs are added later.
+ int capacity = std::max(1, input_count);
if (has_extensible_inputs) {
const int max = kMaxInlineCapacity;
capacity = std::min(input_count + 3, max);
}
- size_t size = sizeof(Node) + capacity * (sizeof(Node*) + sizeof(Use));
- intptr_t raw_buffer = reinterpret_cast<intptr_t>(zone->New(size));
+ size_t size = sizeof(Node) + capacity * (sizeof(ZoneNodePtr) + sizeof(Use));
+ intptr_t raw_buffer =
+ reinterpret_cast<intptr_t>(zone->Allocate<NodeWithInLineInputs>(size));
void* node_buffer =
reinterpret_cast<void*>(raw_buffer + capacity * sizeof(Use));
node = new (node_buffer) Node(id, op, input_count, capacity);
- input_ptr = node->inputs_.inline_;
+ input_ptr = node->inline_inputs();
use_ptr = reinterpret_cast<Use*>(node);
is_inline = true;
}
// Initialize the input pointers and the uses.
+ CHECK_IMPLIES(input_count > 0,
+ Use::InputIndexField::is_valid(input_count - 1));
for (int current = 0; current < input_count; ++current) {
Node* to = *inputs++;
input_ptr[current] = to;
@@ -115,13 +128,17 @@
return node;
}
+Node* Node::New(Zone* zone, NodeId id, const Operator* op, int input_count,
+ Node* const* inputs, bool has_extensible_inputs) {
+ return NewImpl(zone, id, op, input_count, inputs, has_extensible_inputs);
+}
Node* Node::Clone(Zone* zone, NodeId id, const Node* node) {
int const input_count = node->InputCount();
- Node* const* const inputs = node->has_inline_inputs()
- ? node->inputs_.inline_
- : node->inputs_.outline_->inputs_;
- Node* const clone = New(zone, id, node->op(), input_count, inputs, false);
+ ZoneNodePtr const* const inputs = node->has_inline_inputs()
+ ? node->inline_inputs()
+ : node->outline_inputs()->inputs();
+ Node* const clone = NewImpl(zone, id, node->op(), input_count, inputs, false);
clone->set_type(node->type());
return clone;
}
@@ -138,19 +155,20 @@
DCHECK_NOT_NULL(zone);
DCHECK_NOT_NULL(new_to);
- int inline_count = InlineCountField::decode(bit_field_);
- int inline_capacity = InlineCapacityField::decode(bit_field_);
+ int const inline_count = InlineCountField::decode(bit_field_);
+ int const inline_capacity = InlineCapacityField::decode(bit_field_);
if (inline_count < inline_capacity) {
// Append inline input.
bit_field_ = InlineCountField::update(bit_field_, inline_count + 1);
*GetInputPtr(inline_count) = new_to;
Use* use = GetUsePtr(inline_count);
+ STATIC_ASSERT(InlineCapacityField::kMax <= Use::InputIndexField::kMax);
use->bit_field_ = Use::InputIndexField::encode(inline_count) |
Use::InlineField::encode(true);
new_to->AppendUse(use);
} else {
// Append out-of-line input.
- int input_count = InputCount();
+ int const input_count = InputCount();
OutOfLineInputs* outline = nullptr;
if (inline_count != kOutlineMarker) {
// switch to out of line inputs.
@@ -158,21 +176,22 @@
outline->node_ = this;
outline->ExtractFrom(GetUsePtr(0), GetInputPtr(0), input_count);
bit_field_ = InlineCountField::update(bit_field_, kOutlineMarker);
- inputs_.outline_ = outline;
+ set_outline_inputs(outline);
} else {
// use current out of line inputs.
- outline = inputs_.outline_;
+ outline = outline_inputs();
if (input_count >= outline->capacity_) {
// out of space in out-of-line inputs.
outline = OutOfLineInputs::New(zone, input_count * 2 + 3);
outline->node_ = this;
outline->ExtractFrom(GetUsePtr(0), GetInputPtr(0), input_count);
- inputs_.outline_ = outline;
+ set_outline_inputs(outline);
}
}
outline->count_++;
*GetInputPtr(input_count) = new_to;
Use* use = GetUsePtr(input_count);
+ CHECK(Use::InputIndexField::is_valid(input_count));
use->bit_field_ = Use::InputIndexField::encode(input_count) |
Use::InlineField::encode(false);
new_to->AppendUse(use);
@@ -199,9 +218,9 @@
DCHECK_LT(0, count);
DCHECK_LT(index, InputCount());
for (int i = 0; i < count; i++) {
- AppendInput(zone, InputAt(Max(InputCount() - count, 0)));
+ AppendInput(zone, InputAt(std::max(InputCount() - count, 0)));
}
- for (int i = InputCount() - count - 1; i >= Max(index, count); --i) {
+ for (int i = InputCount() - count - 1; i >= std::max(index, count); --i) {
ReplaceInput(i, InputAt(i - count));
}
for (int i = 0; i < count; i++) {
@@ -210,19 +229,20 @@
Verify();
}
-void Node::RemoveInput(int index) {
+Node* Node::RemoveInput(int index) {
DCHECK_LE(0, index);
DCHECK_LT(index, InputCount());
+ Node* result = InputAt(index);
for (; index < InputCount() - 1; ++index) {
ReplaceInput(index, InputAt(index + 1));
}
TrimInputCount(InputCount() - 1);
Verify();
+ return result;
}
-
void Node::ClearInputs(int start, int count) {
- Node** input_ptr = GetInputPtr(start);
+ ZoneNodePtr* input_ptr = GetInputPtr(start);
Use* use_ptr = GetUsePtr(start);
while (count-- > 0) {
DCHECK_EQ(input_ptr, use_ptr->input_ptr());
@@ -247,10 +267,23 @@
if (has_inline_inputs()) {
bit_field_ = InlineCountField::update(bit_field_, new_input_count);
} else {
- inputs_.outline_->count_ = new_input_count;
+ outline_inputs()->count_ = new_input_count;
}
}
+void Node::EnsureInputCount(Zone* zone, int new_input_count) {
+ int current_count = InputCount();
+ DCHECK_NE(current_count, 0);
+ if (current_count > new_input_count) {
+ TrimInputCount(new_input_count);
+ } else if (current_count < new_input_count) {
+ Node* dummy = InputAt(current_count - 1);
+ do {
+ AppendInput(zone, dummy);
+ current_count++;
+ } while (current_count < new_input_count);
+ }
+}
int Node::UseCount() const {
int use_count = 0;
@@ -280,6 +313,17 @@
first_use_ = nullptr;
}
+bool Node::OwnedBy(Node const* owner) const {
+ unsigned mask = 0;
+ for (Use* use = first_use_; use; use = use->next) {
+ if (use->from() == owner) {
+ mask |= 1;
+ } else {
+ return false;
+ }
+ }
+ return mask == 1;
+}
bool Node::OwnedBy(Node const* owner1, Node const* owner2) const {
unsigned mask = 0;
@@ -296,26 +340,32 @@
return mask == 3;
}
-bool Node::OwnedByAddressingOperand() const {
- for (Use* use = first_use_; use; use = use->next) {
- Node* from = use->from();
- if (from->opcode() != IrOpcode::kLoad &&
- // If {from} is store, make sure it does not use {this} as value
- (from->opcode() != IrOpcode::kStore || from->InputAt(2) == this) &&
- from->opcode() != IrOpcode::kInt32Add &&
- from->opcode() != IrOpcode::kInt64Add) {
- return false;
- }
- }
- return true;
+void Node::Print(int depth) const {
+ StdoutStream os;
+ Print(os, depth);
}
-void Node::Print() const {
- OFStream os(stdout);
- os << *this << std::endl;
- for (Node* input : this->inputs()) {
- os << " " << *input << std::endl;
+namespace {
+void PrintNode(const Node* node, std::ostream& os, int depth,
+ int indentation = 0) {
+ for (int i = 0; i < indentation; ++i) {
+ os << " ";
}
+ if (node) {
+ os << *node;
+ } else {
+ os << "(NULL)";
+ }
+ os << std::endl;
+ if (depth <= 0) return;
+ for (Node* input : node->inputs()) {
+ PrintNode(input, os, depth - 1, indentation + 1);
+ }
+}
+} // namespace
+
+void Node::Print(std::ostream& os, int depth) const {
+ PrintNode(this, os, depth);
}
std::ostream& operator<<(std::ostream& os, const Node& n) {
@@ -337,14 +387,17 @@
Node::Node(NodeId id, const Operator* op, int inline_count, int inline_capacity)
: op_(op),
- type_(nullptr),
mark_(0),
bit_field_(IdField::encode(id) | InlineCountField::encode(inline_count) |
InlineCapacityField::encode(inline_capacity)),
first_use_(nullptr) {
+ // Check that the id didn't overflow.
+ STATIC_ASSERT(IdField::kMax < std::numeric_limits<NodeId>::max());
+ CHECK(IdField::is_valid(id));
+
// Inputs must either be out of line or within the inline capacity.
- DCHECK(inline_capacity <= kMaxInlineCapacity);
DCHECK(inline_count == kOutlineMarker || inline_count <= inline_capacity);
+ DCHECK_LE(inline_capacity, kMaxInlineCapacity);
}
@@ -375,7 +428,7 @@
#if DEBUG
void Node::Verify() {
- // Check basic sanity of input data structures.
+ // Check basic validity of input data structures.
fflush(stdout);
int count = this->InputCount();
// Avoid quadratic explosion for mega nodes; only verify if the input
@@ -383,29 +436,29 @@
if (count > 200 && count % 100) return;
for (int i = 0; i < count; i++) {
- CHECK_EQ(i, this->GetUsePtr(i)->input_index());
- CHECK_EQ(this->GetInputPtr(i), this->GetUsePtr(i)->input_ptr());
- CHECK_EQ(count, this->InputCount());
+ DCHECK_EQ(i, this->GetUsePtr(i)->input_index());
+ DCHECK_EQ(this->GetInputPtr(i), this->GetUsePtr(i)->input_ptr());
+ DCHECK_EQ(count, this->InputCount());
}
{ // Direct input iteration.
int index = 0;
for (Node* input : this->inputs()) {
- CHECK_EQ(this->InputAt(index), input);
+ DCHECK_EQ(this->InputAt(index), input);
index++;
}
- CHECK_EQ(count, index);
- CHECK_EQ(this->InputCount(), index);
+ DCHECK_EQ(count, index);
+ DCHECK_EQ(this->InputCount(), index);
}
{ // Input edge iteration.
int index = 0;
for (Edge edge : this->input_edges()) {
- CHECK_EQ(edge.from(), this);
- CHECK_EQ(index, edge.index());
- CHECK_EQ(this->InputAt(index), edge.to());
+ DCHECK_EQ(edge.from(), this);
+ DCHECK_EQ(index, edge.index());
+ DCHECK_EQ(this->InputAt(index), edge.to());
index++;
}
- CHECK_EQ(count, index);
- CHECK_EQ(this->InputCount(), index);
+ DCHECK_EQ(count, index);
+ DCHECK_EQ(this->InputCount(), index);
}
}
#endif