Upgrade V8 to 5.1.281.57  DO NOT MERGE

FPIIM-449

Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/snapshot/serializer.h b/src/snapshot/serializer.h
new file mode 100644
index 0000000..eccbaab
--- /dev/null
+++ b/src/snapshot/serializer.h
@@ -0,0 +1,321 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_SNAPSHOT_SERIALIZER_H_
+#define V8_SNAPSHOT_SERIALIZER_H_
+
+#include "src/isolate.h"
+#include "src/log.h"
+#include "src/objects.h"
+#include "src/snapshot/serializer-common.h"
+#include "src/snapshot/snapshot-source-sink.h"
+
+namespace v8 {
+namespace internal {
+
+class CodeAddressMap : public CodeEventLogger {
+ public:
+  explicit CodeAddressMap(Isolate* isolate) : isolate_(isolate) {
+    isolate->logger()->addCodeEventListener(this);
+  }
+
+  ~CodeAddressMap() override {
+    isolate_->logger()->removeCodeEventListener(this);
+  }
+
+  void CodeMoveEvent(AbstractCode* from, Address to) override {
+    address_to_name_map_.Move(from->address(), to);
+  }
+
+  void CodeDisableOptEvent(AbstractCode* code,
+                           SharedFunctionInfo* shared) override {}
+
+  const char* Lookup(Address address) {
+    return address_to_name_map_.Lookup(address);
+  }
+
+ private:
+  class NameMap {
+   public:
+    NameMap() : impl_(HashMap::PointersMatch) {}
+
+    ~NameMap() {
+      for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
+        DeleteArray(static_cast<const char*>(p->value));
+      }
+    }
+
+    void Insert(Address code_address, const char* name, int name_size) {
+      HashMap::Entry* entry = FindOrCreateEntry(code_address);
+      if (entry->value == NULL) {
+        entry->value = CopyName(name, name_size);
+      }
+    }
+
+    const char* Lookup(Address code_address) {
+      HashMap::Entry* entry = FindEntry(code_address);
+      return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
+    }
+
+    void Remove(Address code_address) {
+      HashMap::Entry* entry = FindEntry(code_address);
+      if (entry != NULL) {
+        DeleteArray(static_cast<char*>(entry->value));
+        RemoveEntry(entry);
+      }
+    }
+
+    void Move(Address from, Address to) {
+      if (from == to) return;
+      HashMap::Entry* from_entry = FindEntry(from);
+      DCHECK(from_entry != NULL);
+      void* value = from_entry->value;
+      RemoveEntry(from_entry);
+      HashMap::Entry* to_entry = FindOrCreateEntry(to);
+      DCHECK(to_entry->value == NULL);
+      to_entry->value = value;
+    }
+
+   private:
+    static char* CopyName(const char* name, int name_size) {
+      char* result = NewArray<char>(name_size + 1);
+      for (int i = 0; i < name_size; ++i) {
+        char c = name[i];
+        if (c == '\0') c = ' ';
+        result[i] = c;
+      }
+      result[name_size] = '\0';
+      return result;
+    }
+
+    HashMap::Entry* FindOrCreateEntry(Address code_address) {
+      return impl_.LookupOrInsert(code_address,
+                                  ComputePointerHash(code_address));
+    }
+
+    HashMap::Entry* FindEntry(Address code_address) {
+      return impl_.Lookup(code_address, ComputePointerHash(code_address));
+    }
+
+    void RemoveEntry(HashMap::Entry* entry) {
+      impl_.Remove(entry->key, entry->hash);
+    }
+
+    HashMap impl_;
+
+    DISALLOW_COPY_AND_ASSIGN(NameMap);
+  };
+
+  void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*,
+                         const char* name, int length) override {
+    address_to_name_map_.Insert(code->address(), name, length);
+  }
+
+  NameMap address_to_name_map_;
+  Isolate* isolate_;
+};
+
+// There can be only one serializer per V8 process.
+class Serializer : public SerializerDeserializer {
+ public:
+  Serializer(Isolate* isolate, SnapshotByteSink* sink);
+  ~Serializer() override;
+
+  void EncodeReservations(List<SerializedData::Reservation>* out) const;
+
+  void SerializeDeferredObjects();
+
+  Isolate* isolate() const { return isolate_; }
+
+  BackReferenceMap* back_reference_map() { return &back_reference_map_; }
+  RootIndexMap* root_index_map() { return &root_index_map_; }
+
+#ifdef OBJECT_PRINT
+  void CountInstanceType(Map* map, int size);
+#endif  // OBJECT_PRINT
+
+ protected:
+  class ObjectSerializer;
+  class RecursionScope {
+   public:
+    explicit RecursionScope(Serializer* serializer) : serializer_(serializer) {
+      serializer_->recursion_depth_++;
+    }
+    ~RecursionScope() { serializer_->recursion_depth_--; }
+    bool ExceedsMaximum() {
+      return serializer_->recursion_depth_ >= kMaxRecursionDepth;
+    }
+
+   private:
+    static const int kMaxRecursionDepth = 32;
+    Serializer* serializer_;
+  };
+
+  virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
+                               WhereToPoint where_to_point, int skip) = 0;
+
+  void VisitPointers(Object** start, Object** end) override;
+
+  void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
+               int skip);
+
+  void PutSmi(Smi* smi);
+
+  void PutBackReference(HeapObject* object, BackReference reference);
+
+  // Emit alignment prefix if necessary, return required padding space in bytes.
+  int PutAlignmentPrefix(HeapObject* object);
+
+  // Returns true if the object was successfully serialized.
+  bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
+                            WhereToPoint where_to_point, int skip);
+
+  inline void FlushSkip(int skip) {
+    if (skip != 0) {
+      sink_->Put(kSkip, "SkipFromSerializeObject");
+      sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
+    }
+  }
+
+  bool BackReferenceIsAlreadyAllocated(BackReference back_reference);
+
+  // This will return the space for an object.
+  BackReference AllocateLargeObject(int size);
+  BackReference Allocate(AllocationSpace space, int size);
+  int EncodeExternalReference(Address addr) {
+    return external_reference_encoder_.Encode(addr);
+  }
+
+  bool HasNotExceededFirstPageOfEachSpace();
+
+  // GetInt reads 4 bytes at once, requiring padding at the end.
+  void Pad();
+
+  // We may not need the code address map for logging for every instance
+  // of the serializer.  Initialize it on demand.
+  void InitializeCodeAddressMap();
+
+  Code* CopyCode(Code* code);
+
+  inline uint32_t max_chunk_size(int space) const {
+    DCHECK_LE(0, space);
+    DCHECK_LT(space, kNumberOfSpaces);
+    return max_chunk_size_[space];
+  }
+
+  SnapshotByteSink* sink() const { return sink_; }
+
+  void QueueDeferredObject(HeapObject* obj) {
+    DCHECK(back_reference_map_.Lookup(obj).is_valid());
+    deferred_objects_.Add(obj);
+  }
+
+  void OutputStatistics(const char* name);
+
+  Isolate* isolate_;
+
+  SnapshotByteSink* sink_;
+  ExternalReferenceEncoder external_reference_encoder_;
+
+  BackReferenceMap back_reference_map_;
+  RootIndexMap root_index_map_;
+
+  int recursion_depth_;
+
+  friend class Deserializer;
+  friend class ObjectSerializer;
+  friend class RecursionScope;
+  friend class SnapshotData;
+
+ private:
+  CodeAddressMap* code_address_map_;
+  // Objects from the same space are put into chunks for bulk-allocation
+  // when deserializing. We have to make sure that each chunk fits into a
+  // page. So we track the chunk size in pending_chunk_ of a space, but
+  // when it exceeds a page, we complete the current chunk and start a new one.
+  uint32_t pending_chunk_[kNumberOfPreallocatedSpaces];
+  List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces];
+  uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces];
+
+  // We map serialized large objects to indexes for back-referencing.
+  uint32_t large_objects_total_size_;
+  uint32_t seen_large_objects_index_;
+
+  List<byte> code_buffer_;
+
+  // To handle stack overflow.
+  List<HeapObject*> deferred_objects_;
+
+#ifdef OBJECT_PRINT
+  static const int kInstanceTypes = 256;
+  int* instance_type_count_;
+  size_t* instance_type_size_;
+#endif  // OBJECT_PRINT
+
+  DISALLOW_COPY_AND_ASSIGN(Serializer);
+};
+
+class Serializer::ObjectSerializer : public ObjectVisitor {
+ public:
+  ObjectSerializer(Serializer* serializer, HeapObject* obj,
+                   SnapshotByteSink* sink, HowToCode how_to_code,
+                   WhereToPoint where_to_point)
+      : serializer_(serializer),
+        object_(obj),
+        sink_(sink),
+        reference_representation_(how_to_code + where_to_point),
+        bytes_processed_so_far_(0),
+        code_has_been_output_(false) {}
+  ~ObjectSerializer() override {}
+  void Serialize();
+  void SerializeDeferred();
+  void VisitPointers(Object** start, Object** end) override;
+  void VisitEmbeddedPointer(RelocInfo* target) override;
+  void VisitExternalReference(Address* p) override;
+  void VisitExternalReference(RelocInfo* rinfo) override;
+  void VisitInternalReference(RelocInfo* rinfo) override;
+  void VisitCodeTarget(RelocInfo* target) override;
+  void VisitCodeEntry(Address entry_address) override;
+  void VisitCell(RelocInfo* rinfo) override;
+  void VisitRuntimeEntry(RelocInfo* reloc) override;
+  // Used for seralizing the external strings that hold the natives source.
+  void VisitExternalOneByteString(
+      v8::String::ExternalOneByteStringResource** resource) override;
+  // We can't serialize a heap with external two byte strings.
+  void VisitExternalTwoByteString(
+      v8::String::ExternalStringResource** resource) override {
+    UNREACHABLE();
+  }
+
+ private:
+  void SerializePrologue(AllocationSpace space, int size, Map* map);
+
+  bool SerializeExternalNativeSourceString(
+      int builtin_count,
+      v8::String::ExternalOneByteStringResource** resource_pointer,
+      FixedArray* source_cache, int resource_index);
+
+  enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn };
+  // This function outputs or skips the raw data between the last pointer and
+  // up to the current position.  It optionally can just return the number of
+  // bytes to skip instead of performing a skip instruction, in case the skip
+  // can be merged into the next instruction.
+  int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn);
+  // External strings are serialized in a way to resemble sequential strings.
+  void SerializeExternalString();
+
+  Address PrepareCode();
+
+  Serializer* serializer_;
+  HeapObject* object_;
+  SnapshotByteSink* sink_;
+  int reference_representation_;
+  int bytes_processed_so_far_;
+  bool code_has_been_output_;
+};
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_SNAPSHOT_SERIALIZER_H_