Update V8 to r4588

We're using WebKit r58033, as used by
http://src.chromium.org/svn/releases/5.0.387.0/DEPS
This requires http://v8.googlecode.com/svn/trunk@4465 but this version has a
crashing bug for ARM. Instead we use http://v8.googlecode.com/svn/trunk@4588,
which is used by http://src.chromium.org/svn/releases/6.0.399.0/DEPS

Note that a trivial bug fix was required in arm/codegen-arm.cc. This is guarded
with ANDROID. See http://code.google.com/p/v8/issues/detail?id=703

Change-Id: I459647a8286c4f8c7405f0c5581ecbf051a6f1e8
diff --git a/src/data-flow.h b/src/data-flow.h
index 2331944..079da65 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -28,12 +28,186 @@
 #ifndef V8_DATAFLOW_H_
 #define V8_DATAFLOW_H_
 
+#include "v8.h"
+
 #include "ast.h"
 #include "compiler.h"
+#include "zone-inl.h"
 
 namespace v8 {
 namespace internal {
 
+// Forward declarations.
+class Node;
+
+class BitVector: public ZoneObject {
+ public:
+  explicit BitVector(int length)
+      : length_(length),
+        data_length_(SizeFor(length)),
+        data_(Zone::NewArray<uint32_t>(data_length_)) {
+    ASSERT(length > 0);
+    Clear();
+  }
+
+  BitVector(const BitVector& other)
+      : length_(other.length()),
+        data_length_(SizeFor(length_)),
+        data_(Zone::NewArray<uint32_t>(data_length_)) {
+    CopyFrom(other);
+  }
+
+  static int SizeFor(int length) {
+    return 1 + ((length - 1) / 32);
+  }
+
+  BitVector& operator=(const BitVector& rhs) {
+    if (this != &rhs) CopyFrom(rhs);
+    return *this;
+  }
+
+  void CopyFrom(const BitVector& other) {
+    ASSERT(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] = other.data_[i];
+    }
+  }
+
+  bool Contains(int i) {
+    ASSERT(i >= 0 && i < length());
+    uint32_t block = data_[i / 32];
+    return (block & (1U << (i % 32))) != 0;
+  }
+
+  void Add(int i) {
+    ASSERT(i >= 0 && i < length());
+    data_[i / 32] |= (1U << (i % 32));
+  }
+
+  void Remove(int i) {
+    ASSERT(i >= 0 && i < length());
+    data_[i / 32] &= ~(1U << (i % 32));
+  }
+
+  void Union(const BitVector& other) {
+    ASSERT(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] |= other.data_[i];
+    }
+  }
+
+  void Intersect(const BitVector& other) {
+    ASSERT(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] &= other.data_[i];
+    }
+  }
+
+  void Subtract(const BitVector& other) {
+    ASSERT(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] &= ~other.data_[i];
+    }
+  }
+
+  void Clear() {
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] = 0;
+    }
+  }
+
+  bool IsEmpty() const {
+    for (int i = 0; i < data_length_; i++) {
+      if (data_[i] != 0) return false;
+    }
+    return true;
+  }
+
+  bool Equals(const BitVector& other) {
+    for (int i = 0; i < data_length_; i++) {
+      if (data_[i] != other.data_[i]) return false;
+    }
+    return true;
+  }
+
+  int length() const { return length_; }
+
+#ifdef DEBUG
+  void Print();
+#endif
+
+ private:
+  int length_;
+  int data_length_;
+  uint32_t* data_;
+};
+
+
+// Simple fixed-capacity list-based worklist (managed as a queue) of
+// pointers to T.
+template<typename T>
+class WorkList BASE_EMBEDDED {
+ public:
+  // The worklist cannot grow bigger than size.  We keep one item empty to
+  // distinguish between empty and full.
+  explicit WorkList(int size)
+      : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
+    for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
+  }
+
+  bool is_empty() { return head_ == tail_; }
+
+  bool is_full() {
+    // The worklist is full if head is at 0 and tail is at capacity - 1:
+    //   head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
+    // or if tail is immediately to the left of head:
+    //   tail+1 == head  ==> tail - head == -1
+    int diff = tail_ - head_;
+    return (diff == -1 || diff == capacity_ - 1);
+  }
+
+  void Insert(T* item) {
+    ASSERT(!is_full());
+    queue_[tail_++] = item;
+    if (tail_ == capacity_) tail_ = 0;
+  }
+
+  T* Remove() {
+    ASSERT(!is_empty());
+    T* item = queue_[head_++];
+    if (head_ == capacity_) head_ = 0;
+    return item;
+  }
+
+ private:
+  int capacity_;  // Including one empty slot.
+  int head_;      // Where the first item is.
+  int tail_;      // Where the next inserted item will go.
+  List<T*> queue_;
+};
+
+
+struct ReachingDefinitionsData BASE_EMBEDDED {
+ public:
+  ReachingDefinitionsData() : rd_in_(NULL), kill_(NULL), gen_(NULL) {}
+
+  void Initialize(int definition_count) {
+    rd_in_ = new BitVector(definition_count);
+    kill_ = new BitVector(definition_count);
+    gen_ = new BitVector(definition_count);
+  }
+
+  BitVector* rd_in() { return rd_in_; }
+  BitVector* kill() { return kill_; }
+  BitVector* gen() { return gen_; }
+
+ private:
+  BitVector* rd_in_;
+  BitVector* kill_;
+  BitVector* gen_;
+};
+
+
 // This class is used to number all expressions in the AST according to
 // their evaluation order (post-order left-to-right traversal).
 class AstLabeler: public AstVisitor {
@@ -62,52 +236,39 @@
 };
 
 
-class VarUseMap : public HashMap {
+// Computes the set of assigned variables and annotates variables proxies
+// that are trivial sub-expressions and for-loops where the loop variable
+// is guaranteed to be a smi.
+class AssignedVariablesAnalyzer : public AstVisitor {
  public:
-  VarUseMap() : HashMap(VarMatch) {}
+  explicit AssignedVariablesAnalyzer(FunctionLiteral* fun);
 
-  ZoneList<Expression*>* Lookup(Variable* var);
+  void Analyze();
 
  private:
-  static bool VarMatch(void* key1, void* key2) { return key1 == key2; }
-};
+  Variable* FindSmiLoopVariable(ForStatement* stmt);
 
+  int BitIndex(Variable* var);
 
-class DefinitionInfo : public ZoneObject {
- public:
-  explicit DefinitionInfo() : last_use_(NULL) {}
+  void RecordAssignedVar(Variable* var);
 
-  Expression* last_use() { return last_use_; }
-  void set_last_use(Expression* expr) { last_use_ = expr; }
+  void MarkIfTrivial(Expression* expr);
 
- private:
-  Expression* last_use_;
-  Register location_;
-};
-
-
-class LivenessAnalyzer : public AstVisitor {
- public:
-  LivenessAnalyzer() {}
-
-  void Analyze(FunctionLiteral* fun);
-
- private:
-  void VisitStatements(ZoneList<Statement*>* stmts);
-
-  void RecordUse(Variable* var, Expression* expr);
-  void RecordDef(Variable* var, Expression* expr);
-
+  // Visits an expression saving the accumulator before, clearing
+  // it before visting and restoring it after visiting.
+  void ProcessExpression(Expression* expr);
 
   // AST node visit functions.
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
-  // Map for tracking the live variables.
-  VarUseMap live_vars_;
+  FunctionLiteral* fun_;
 
-  DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer);
+  // Accumulator for assigned variables set.
+  BitVector av_;
+
+  DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer);
 };