Revision: 19310
Author: [email protected]
Date: Wed Feb 12 08:46:31 2014 UTC
Log: A64: Synchronize with r19306.
This brings experimental/a64 up to 2014-02-12.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/159843003
http://code.google.com/p/v8/source/detail?r=19310
Modified:
/branches/experimental/a64/ChangeLog
/branches/experimental/a64/src/hydrogen-check-elimination.cc
/branches/experimental/a64/src/hydrogen-flow-engine.h
/branches/experimental/a64/src/hydrogen-load-elimination.cc
/branches/experimental/a64/src/hydrogen.cc
/branches/experimental/a64/src/hydrogen.h
/branches/experimental/a64/src/incremental-marking.h
/branches/experimental/a64/src/version.cc
/branches/experimental/a64/test/cctest/cctest.status
=======================================
--- /branches/experimental/a64/ChangeLog Tue Feb 11 17:36:50 2014 UTC
+++ /branches/experimental/a64/ChangeLog Wed Feb 12 08:46:31 2014 UTC
@@ -1,3 +1,10 @@
+2014-02-12: Version 3.24.37
+
+ Fix spec violations in JSON.stringify wrt replacer array (issue
3135).
+
+ Performance and stability improvements on all platforms.
+
+
2014-02-11: Version 3.24.36
Fix inconsistencies wrt whitespaces (issue 3109).
=======================================
--- /branches/experimental/a64/src/hydrogen-check-elimination.cc Tue Feb 11
17:36:50 2014 UTC
+++ /branches/experimental/a64/src/hydrogen-check-elimination.cc Wed Feb 12
08:46:31 2014 UTC
@@ -116,16 +116,49 @@
return this;
}
- // Global analysis: Copy state to successor block.
+ // Support for global analysis with HFlowEngine: Merge given state with
+ // the other incoming state.
+ static HCheckTable* Merge(HCheckTable* succ_state, HBasicBlock*
succ_block,
+ HCheckTable* pred_state, HBasicBlock*
pred_block,
+ Zone* zone) {
+ if (pred_state == NULL || pred_block->IsUnreachable()) {
+ return succ_state;
+ }
+ if (succ_state == NULL) {
+ return pred_state->Copy(succ_block, pred_block, zone);
+ } else {
+ return succ_state->Merge(succ_block, pred_state, pred_block, zone);
+ }
+ }
+
+ // Support for global analysis with HFlowEngine: Given state merged with
all
+ // the other incoming states, prepare it for use.
+ static HCheckTable* Finish(HCheckTable* state, HBasicBlock* block,
+ Zone* zone) {
+ if (state == NULL) {
+ block->MarkUnreachable();
+ }
+ return state;
+ }
+
+ private:
+ // Copy state to successor block.
HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone*
zone) {
HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_);
for (int i = 0; i < size_; i++) {
HCheckTableEntry* old_entry = &entries_[i];
HCheckTableEntry* new_entry = ©->entries_[i];
- // TODO(titzer): keep the check if this block dominates the
successor?
new_entry->object_ = old_entry->object_;
- new_entry->check_ = NULL;
new_entry->maps_ = old_entry->maps_->Copy(phase_->zone());
+ // Keep the check if the existing check's block dominates the
successor.
+ if (old_entry->check_ != NULL &&
+ old_entry->check_->block()->Dominates(succ)) {
+ new_entry->check_ = old_entry->check_;
+ } else {
+ // Leave it NULL till we meet a new check instruction for this
object
+ // in the control flow.
+ new_entry->check_ = NULL;
+ }
}
copy->cursor_ = cursor_;
copy->size_ = size_;
@@ -150,22 +183,31 @@
// Branch-sensitive analysis for certain comparisons may add more facts
// to the state for the successor on the true branch.
bool learned = false;
- HControlInstruction* end = succ->predecessors()->at(0)->end();
- if (succ->predecessors()->length() == 1 && end->SuccessorAt(0) ==
succ) {
+ if (succ->predecessors()->length() == 1) {
+ HControlInstruction* end = succ->predecessors()->at(0)->end();
+ bool is_true_branch = end->SuccessorAt(0) == succ;
if (end->IsCompareMap()) {
- // Learn on the true branch of if(CompareMap(x)).
HCompareMap* cmp = HCompareMap::cast(end);
HValue* object = cmp->value()->ActualValue();
HCheckTableEntry* entry = copy->Find(object);
- if (entry == NULL) {
- copy->Insert(object, cmp->map());
+ if (is_true_branch) {
+ // Learn on the true branch of if(CompareMap(x)).
+ if (entry == NULL) {
+ copy->Insert(object, cmp, cmp->map());
+ } else {
+ MapSet list = new(phase_->zone()) UniqueSet<Map>();
+ list->Add(cmp->map(), phase_->zone());
+ entry->maps_ = list;
+ entry->check_ = cmp;
+ }
} else {
- MapSet list = new(phase_->zone()) UniqueSet<Map>();
- list->Add(cmp->map(), phase_->zone());
- entry->maps_ = list;
+ // Learn on the false branch of if(CompareMap(x)).
+ if (entry != NULL) {
+ entry->maps_->Remove(cmp->map());
+ }
}
learned = true;
- } else if (end->IsCompareObjectEqAndBranch()) {
+ } else if (is_true_branch && end->IsCompareObjectEqAndBranch()) {
// Learn on the true branch of if(CmpObjectEq(x, y)).
HCompareObjectEqAndBranch* cmp =
HCompareObjectEqAndBranch::cast(end);
@@ -200,45 +242,44 @@
return copy;
}
- // Global analysis: Merge this state with the other incoming state.
+ // Merge this state with the other incoming state.
HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that,
HBasicBlock* pred_block, Zone* zone) {
- if (pred_block->IsReachable()) {
- if (that->size_ == 0) {
- // If the other state is empty, simply reset.
- size_ = 0;
- cursor_ = 0;
- } else {
- int pred_index = succ->PredecessorIndexOf(pred_block);
- bool compact = false;
- for (int i = 0; i < size_; i++) {
- HCheckTableEntry* this_entry = &entries_[i];
- HCheckTableEntry* that_entry;
- if (this_entry->object_->IsPhi() &&
- this_entry->object_->block() == succ) {
- HPhi* phi = HPhi::cast(this_entry->object_);
- HValue* phi_operand = phi->OperandAt(pred_index);
- that_entry = that->Find(phi_operand);
+ if (that->size_ == 0) {
+ // If the other state is empty, simply reset.
+ size_ = 0;
+ cursor_ = 0;
+ } else {
+ int pred_index = succ->PredecessorIndexOf(pred_block);
+ bool compact = false;
+ for (int i = 0; i < size_; i++) {
+ HCheckTableEntry* this_entry = &entries_[i];
+ HCheckTableEntry* that_entry;
+ if (this_entry->object_->IsPhi() &&
+ this_entry->object_->block() == succ) {
+ HPhi* phi = HPhi::cast(this_entry->object_);
+ HValue* phi_operand = phi->OperandAt(pred_index);
+ that_entry = that->Find(phi_operand);
- } else {
- that_entry = that->Find(this_entry->object_);
- }
+ } else {
+ that_entry = that->Find(this_entry->object_);
+ }
- if (that_entry == NULL) {
- this_entry->object_ = NULL;
- compact = true;
- } else {
- this_entry->maps_ =
- this_entry->maps_->Union(that_entry->maps_,
phase_->zone());
- if (this_entry->check_ != that_entry->check_) {
- this_entry->check_ = NULL;
- }
- ASSERT(this_entry->maps_->size() > 0);
+ if (that_entry == NULL) {
+ this_entry->object_ = NULL;
+ compact = true;
+ } else {
+ this_entry->maps_ =
+ this_entry->maps_->Union(that_entry->maps_, phase_->zone());
+ if (this_entry->check_ != that_entry->check_) {
+ this_entry->check_ = NULL;
}
+ ASSERT(this_entry->maps_->size() > 0);
}
- if (compact) Compact();
}
+ if (compact) Compact();
}
+
if (FLAG_trace_check_elimination) {
PrintF("B%d checkmaps-table merged with B%d table:\n",
succ->block_id(), pred_block->block_id());
@@ -347,22 +388,32 @@
HValue* object = instr->value()->ActualValue();
// Match a HCheckMapValue(object, HConstant(map))
Unique<Map> map = MapConstant(instr->map());
- MapSet maps = FindMaps(object);
- if (maps != NULL) {
+
+ HCheckTableEntry* entry = Find(object);
+ if (entry != NULL) {
+ MapSet maps = entry->maps_;
if (maps->Contains(map)) {
if (maps->size() == 1) {
// Object is known to have exactly this map.
- instr->DeleteAndReplaceWith(NULL);
+ if (entry->check_ != NULL) {
+ instr->DeleteAndReplaceWith(entry->check_);
+ } else {
+ // Mark check as dead but leave it in the graph as a
checkpoint for
+ // subsequent checks.
+ instr->SetFlag(HValue::kIsDead);
+ entry->check_ = instr;
+ }
INC_STAT(removed_);
} else {
// Only one map survives the check.
maps->Clear();
maps->Add(map, phase_->zone());
+ entry->check_ = instr;
}
}
} else {
// No prior information.
- Insert(object, map);
+ Insert(object, instr, map);
}
}
@@ -379,12 +430,12 @@
if (instr->has_transition()) {
// This store transitions the object to a new map.
Kill(object);
- Insert(object, MapConstant(instr->transition()));
+ Insert(object, NULL, MapConstant(instr->transition()));
} else if (IsMapAccess(instr->access())) {
// This is a store directly to the map field of the object.
Kill(object);
if (!instr->value()->IsConstant()) return;
- Insert(object, MapConstant(instr->value()));
+ Insert(object, NULL, MapConstant(instr->value()));
} else {
// If the instruction changes maps, it should be handled above.
CHECK(!instr->CheckChangesFlag(kMaps));
@@ -394,19 +445,29 @@
void ReduceCompareMap(HCompareMap* instr) {
MapSet maps = FindMaps(instr->value()->ActualValue());
if (maps == NULL) return;
+
+ int succ;
if (maps->Contains(instr->map())) {
- if (maps->size() == 1) {
- TRACE(("Marking redundant CompareMap #%d at B%d as true\n",
- instr->id(), instr->block()->block_id()));
- instr->set_known_successor_index(0);
- INC_STAT(compares_true_);
+ if (maps->size() != 1) {
+ TRACE(("CompareMap #%d for #%d at B%d can't be eliminated: "
+ "ambiguous set of maps\n", instr->id(),
instr->value()->id(),
+ instr->block()->block_id()));
+ return;
}
+ succ = 0;
+ INC_STAT(compares_true_);
} else {
- TRACE(("Marking redundant CompareMap #%d at B%d as false\n",
- instr->id(), instr->block()->block_id()));
- instr->set_known_successor_index(1);
+ succ = 1;
INC_STAT(compares_false_);
}
+
+ TRACE(("Marking redundant CompareMap #%d for #%d at B%d as %s\n",
+ instr->id(), instr->value()->id(), instr->block()->block_id(),
+ succ == 0 ? "true" : "false"));
+ instr->set_known_successor_index(succ);
+
+ int unreachable_succ = 1 - succ;
+ instr->block()->MarkSuccEdgeUnreachable(unreachable_succ);
}
void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
@@ -482,8 +543,7 @@
HCheckTableEntry* entry = &entries_[i];
ASSERT(entry->object_ != NULL);
PrintF(" checkmaps-table @%d: %s #%d ", i,
- entry->object_->IsPhi() ? "phi" : "object",
- entry->object_->id());
+ entry->object_->IsPhi() ? "phi" : "object",
entry->object_->id());
if (entry->check_ != NULL) {
PrintF("check #%d ", entry->check_->id());
}
@@ -497,7 +557,6 @@
}
}
- private:
HCheckTableEntry* Find(HValue* object) {
for (int i = size_ - 1; i >= 0; i--) {
// Search from most-recently-inserted to least-recently-inserted.
@@ -513,13 +572,13 @@
return entry == NULL ? NULL : entry->maps_;
}
- void Insert(HValue* object, Unique<Map> map) {
+ void Insert(HValue* object, HInstruction* check, Unique<Map> map) {
MapSet list = new(phase_->zone()) UniqueSet<Map>();
list->Add(map, phase_->zone());
- Insert(object, NULL, list);
+ Insert(object, check, list);
}
- void Insert(HValue* object, HCheckMaps* check, MapSet maps) {
+ void Insert(HValue* object, HInstruction* check, MapSet maps) {
HCheckTableEntry* entry = &entries_[cursor_++];
entry->object_ = object;
entry->check_ = check;
@@ -538,6 +597,7 @@
}
friend class HCheckMapsEffects;
+ friend class HCheckEliminationPhase;
HCheckEliminationPhase* phase_;
HCheckTableEntry entries_[kMaxTrackedObjects];
=======================================
--- /branches/experimental/a64/src/hydrogen-flow-engine.h Mon Feb 10
13:49:07 2014 UTC
+++ /branches/experimental/a64/src/hydrogen-flow-engine.h Wed Feb 12
08:46:31 2014 UTC
@@ -122,9 +122,10 @@
// Skip blocks not dominated by the root node.
if (SkipNonDominatedBlock(root, block)) continue;
- State* state = StateAt(block);
+ State* state = State::Finish(StateAt(block), block, zone_);
if (block->IsReachable()) {
+ ASSERT(state != NULL);
if (block->IsLoopHeader()) {
// Apply loop effects before analyzing loop body.
ComputeLoopEffects(block)->Apply(state);
@@ -144,18 +145,14 @@
for (int i = 0; i < max; i++) {
HBasicBlock* succ = block->end()->SuccessorAt(i);
IncrementPredecessorCount(succ);
- if (StateAt(succ) == NULL) {
- // This is the first state to reach the successor.
- if (max == 1 && succ->predecessors()->length() == 1) {
- // Optimization: successor can inherit this state.
- SetStateAt(succ, state);
- } else {
- // Successor needs a copy of the state.
- SetStateAt(succ, state->Copy(succ, block, zone_));
- }
+
+ if (max == 1 && succ->predecessors()->length() == 1) {
+ // Optimization: successor can inherit this state.
+ SetStateAt(succ, state);
} else {
// Merge the current state with the state already at the
successor.
- SetStateAt(succ, StateAt(succ)->Merge(succ, state, block,
zone_));
+ SetStateAt(succ,
+ State::Merge(StateAt(succ), succ, state, block,
zone_));
}
}
}
=======================================
--- /branches/experimental/a64/src/hydrogen-load-elimination.cc Tue Feb 11
17:36:50 2014 UTC
+++ /branches/experimental/a64/src/hydrogen-load-elimination.cc Wed Feb 12
08:46:31 2014 UTC
@@ -132,8 +132,32 @@
return this;
}
- // Support for global analysis with HFlowEngine: Copy state to successor
- // block.
+ // Support for global analysis with HFlowEngine: Merge given state with
+ // the other incoming state.
+ static HLoadEliminationTable* Merge(HLoadEliminationTable* succ_state,
+ HBasicBlock* succ_block,
+ HLoadEliminationTable* pred_state,
+ HBasicBlock* pred_block,
+ Zone* zone) {
+ ASSERT(pred_state != NULL);
+ if (succ_state == NULL) {
+ return pred_state->Copy(succ_block, pred_block, zone);
+ } else {
+ return succ_state->Merge(succ_block, pred_state, pred_block, zone);
+ }
+ }
+
+ // Support for global analysis with HFlowEngine: Given state merged with
all
+ // the other incoming states, prepare it for use.
+ static HLoadEliminationTable* Finish(HLoadEliminationTable* state,
+ HBasicBlock* block,
+ Zone* zone) {
+ ASSERT(state != NULL);
+ return state;
+ }
+
+ private:
+ // Copy state to successor block.
HLoadEliminationTable* Copy(HBasicBlock* succ, HBasicBlock* from_block,
Zone* zone) {
HLoadEliminationTable* copy =
@@ -149,8 +173,7 @@
return copy;
}
- // Support for global analysis with HFlowEngine: Merge this state with
- // the other incoming state.
+ // Merge this state with the other incoming state.
HLoadEliminationTable* Merge(HBasicBlock* succ, HLoadEliminationTable*
that,
HBasicBlock* that_block, Zone* zone) {
if (that->fields_.length() < fields_.length()) {
=======================================
--- /branches/experimental/a64/src/hydrogen.cc Tue Feb 11 17:36:50 2014 UTC
+++ /branches/experimental/a64/src/hydrogen.cc Wed Feb 12 08:46:31 2014 UTC
@@ -337,6 +337,15 @@
loop_information()->RegisterBackEdge(predecessors()->at(i));
}
}
+
+
+void HBasicBlock::MarkSuccEdgeUnreachable(int succ) {
+ ASSERT(IsFinished());
+ HBasicBlock* succ_block = end()->SuccessorAt(succ);
+
+ ASSERT(succ_block->predecessors()->length() == 1);
+ succ_block->MarkUnreachable();
+}
void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
=======================================
--- /branches/experimental/a64/src/hydrogen.h Mon Feb 10 17:52:31 2014 UTC
+++ /branches/experimental/a64/src/hydrogen.h Wed Feb 12 08:46:31 2014 UTC
@@ -173,6 +173,8 @@
void MarkAsLoopSuccessorDominator() {
dominates_loop_successors_ = true;
}
+
+ void MarkSuccEdgeUnreachable(int succ);
inline Zone* zone() const;
=======================================
--- /branches/experimental/a64/src/incremental-marking.h Wed May 29
11:13:59 2013 UTC
+++ /branches/experimental/a64/src/incremental-marking.h Wed Feb 12
08:46:31 2014 UTC
@@ -100,7 +100,7 @@
// Do some marking every time this much memory has been allocated or
that many
// heavy (color-checking) write barriers have been invoked.
static const intptr_t kAllocatedThreshold = 65536;
- static const intptr_t kWriteBarriersInvokedThreshold = 65536;
+ static const intptr_t kWriteBarriersInvokedThreshold = 32768;
// Start off by marking this many times more memory than has been
allocated.
static const intptr_t kInitialMarkingSpeed = 1;
// But if we are promoting a lot of data we need to mark faster to keep
up
=======================================
--- /branches/experimental/a64/src/version.cc Tue Feb 11 17:36:50 2014 UTC
+++ /branches/experimental/a64/src/version.cc Wed Feb 12 08:46:31 2014 UTC
@@ -34,7 +34,7 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 24
-#define BUILD_NUMBER 37
+#define BUILD_NUMBER 38
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /branches/experimental/a64/test/cctest/cctest.status Mon Feb 10
17:01:19 2014 UTC
+++ /branches/experimental/a64/test/cctest/cctest.status Wed Feb 12
08:46:31 2014 UTC
@@ -208,5 +208,8 @@
# BUG(2998).
'test-macro-assembler-arm/LoadAndStoreWithRepresentation': [SKIP],
+
+ # BUG(3150).
+ 'test-api/PreCompileInvalidPreparseDataError': [SKIP],
}], # 'arch == nacl_ia32 or arch == nacl_x64'
]
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.