⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialize.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
  // Stat counters#define COUNTER_ENTRY(name, caption) \  Add(reinterpret_cast<Address>(GetInternalPointer(&Counters::name)), \      STATS_COUNTER, \      Counters::k_##name, \      "Counters::" #name);  STATS_COUNTER_LIST_1(COUNTER_ENTRY)  STATS_COUNTER_LIST_2(COUNTER_ENTRY)#undef COUNTER_ENTRY  // Top addresses  const char* top_address_format = "Top::get_address_from_id(%i)";  size_t top_format_length = strlen(top_address_format);  for (uint16_t i = 0; i < Top::k_top_address_count; ++i) {    Vector<char> name = Vector<char>::New(top_format_length + 1);    const char* chars = name.start();    OS::SNPrintF(name, top_address_format, i);    Add(Top::get_address_from_id((Top::AddressId)i), TOP_ADDRESS, i, chars);  }  // Extensions  Add(FUNCTION_ADDR(GCExtension::GC), EXTENSION, 1,      "GCExtension::GC");  Add(FUNCTION_ADDR(PrintExtension::Print), EXTENSION, 2,      "PrintExtension::Print");  Add(FUNCTION_ADDR(LoadExtension::Load), EXTENSION, 3,      "LoadExtension::Load");  Add(FUNCTION_ADDR(QuitExtension::Quit), EXTENSION, 4,      "QuitExtension::Quit");  // Accessors#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \  Add((Address)&Accessors::name, \      ACCESSOR, \      Accessors::k##name, \      "Accessors::" #name);  ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)#undef ACCESSOR_DESCRIPTOR_DECLARATION  // Stub cache tables  Add(SCTableReference::keyReference(StubCache::kPrimary).address(),      STUB_CACHE_TABLE,      1,      "StubCache::primary_->key");  Add(SCTableReference::valueReference(StubCache::kPrimary).address(),      STUB_CACHE_TABLE,      2,      "StubCache::primary_->value");  Add(SCTableReference::keyReference(StubCache::kSecondary).address(),      STUB_CACHE_TABLE,      3,      "StubCache::secondary_->key");  Add(SCTableReference::valueReference(StubCache::kSecondary).address(),      STUB_CACHE_TABLE,      4,      "StubCache::secondary_->value");  // Runtime entries  Add(FUNCTION_ADDR(Runtime::PerformGC),      RUNTIME_ENTRY,      1,      "Runtime::PerformGC");  // Miscellaneous  Add(ExternalReference::builtin_passed_function().address(),      UNCLASSIFIED,      1,      "Builtins::builtin_passed_function");  Add(ExternalReference::the_hole_value_location().address(),      UNCLASSIFIED,      2,      "Factory::the_hole_value().location()");  Add(ExternalReference::address_of_stack_guard_limit().address(),      UNCLASSIFIED,      3,      "StackGuard::address_of_limit()");  Add(ExternalReference::debug_break().address(),      UNCLASSIFIED,      4,      "Debug::Break()");  Add(ExternalReference::new_space_start().address(),      UNCLASSIFIED,      5,      "Heap::NewSpaceStart()");  Add(ExternalReference::new_space_allocation_limit_address().address(),      UNCLASSIFIED,      6,      "Heap::NewSpaceAllocationLimitAddress()");  Add(ExternalReference::new_space_allocation_top_address().address(),      UNCLASSIFIED,      7,      "Heap::NewSpaceAllocationTopAddress()");  Add(ExternalReference::debug_step_in_fp_address().address(),      UNCLASSIFIED,      8,      "Debug::step_in_fp_addr()");}ExternalReferenceEncoder::ExternalReferenceEncoder()    : encodings_(Match) {  ExternalReferenceTable* external_references =      ExternalReferenceTable::instance();  for (int i = 0; i < external_references->size(); ++i) {    Put(external_references->address(i), i);  }}uint32_t ExternalReferenceEncoder::Encode(Address key) const {  int index = IndexOf(key);  return index >=0 ? ExternalReferenceTable::instance()->code(index) : 0;}const char* ExternalReferenceEncoder::NameOfAddress(Address key) const {  int index = IndexOf(key);  return index >=0 ? ExternalReferenceTable::instance()->name(index) : NULL;}int ExternalReferenceEncoder::IndexOf(Address key) const {  if (key == NULL) return -1;  HashMap::Entry* entry =      const_cast<HashMap &>(encodings_).Lookup(key, Hash(key), false);  return entry == NULL ? -1 : reinterpret_cast<int>(entry->value);}void ExternalReferenceEncoder::Put(Address key, int index) {  HashMap::Entry* entry = encodings_.Lookup(key, Hash(key), true);  entry->value = reinterpret_cast<void *>(index);}ExternalReferenceDecoder::ExternalReferenceDecoder()  : encodings_(NewArray<Address*>(kTypeCodeCount)) {  ExternalReferenceTable* external_references =      ExternalReferenceTable::instance();  for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {    int max = external_references->max_id(type) + 1;    encodings_[type] = NewArray<Address>(max + 1);  }  for (int i = 0; i < external_references->size(); ++i) {    Put(external_references->code(i), external_references->address(i));  }}ExternalReferenceDecoder::~ExternalReferenceDecoder() {  for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {    DeleteArray(encodings_[type]);  }  DeleteArray(encodings_);}//------------------------------------------------------------------------------// Implementation of Serializer// Helper class to write the bytes of the serialized heap.class SnapshotWriter { public:  SnapshotWriter() {    len_ = 0;    max_ = 8 << 10;  // 8K initial size    str_ = NewArray<char>(max_);  }  ~SnapshotWriter() {    DeleteArray(str_);  }  void GetString(char** str, int* len) {    *str = NewArray<char>(len_);    memcpy(*str, str_, len_);    *len = len_;  }  void Reserve(int bytes, int pos);  void PutC(char c) {    InsertC(c, len_);  }  void PutInt(int i) {    InsertInt(i, len_);  }  void PutBytes(const byte* a, int size) {    InsertBytes(a, len_, size);  }  void PutString(const char* s) {    InsertString(s, len_);  }  int InsertC(char c, int pos) {    Reserve(1, pos);    str_[pos] = c;    len_++;    return pos + 1;  }  int InsertInt(int i, int pos) {    return InsertBytes(reinterpret_cast<byte*>(&i), pos, sizeof(i));  }  int InsertBytes(const byte* a, int pos, int size) {    Reserve(size, pos);    memcpy(&str_[pos], a, size);    len_ += size;    return pos + size;  }  int InsertString(const char* s, int pos);  int length() { return len_; }  Address position() { return reinterpret_cast<Address>(&str_[len_]); } private:  char* str_;  // the snapshot  int len_;   // the curent length of str_  int max_;   // the allocated size of str_};void SnapshotWriter::Reserve(int bytes, int pos) {  CHECK(0 <= pos && pos <= len_);  while (len_ + bytes >= max_) {    max_ *= 2;    char* old = str_;    str_ = NewArray<char>(max_);    memcpy(str_, old, len_);    DeleteArray(old);  }  if (pos < len_) {    char* old = str_;    str_ = NewArray<char>(max_);    memcpy(str_, old, pos);    memcpy(str_ + pos + bytes, old + pos, len_ - pos);    DeleteArray(old);  }}int SnapshotWriter::InsertString(const char* s, int pos) {  int size = strlen(s);  pos = InsertC('[', pos);  pos = InsertInt(size, pos);  pos = InsertC(']', pos);  return InsertBytes(reinterpret_cast<const byte*>(s), pos, size);}class ReferenceUpdater: public ObjectVisitor { public:  ReferenceUpdater(HeapObject* obj, Serializer* serializer)    : obj_address_(obj->address()),      serializer_(serializer),      reference_encoder_(serializer->reference_encoder_),      offsets_(8),      addresses_(8) {  }  virtual void VisitPointers(Object** start, Object** end) {    for (Object** p = start; p < end; ++p) {      if ((*p)->IsHeapObject()) {        offsets_.Add(reinterpret_cast<Address>(p) - obj_address_);        Address a = serializer_->GetSavedAddress(HeapObject::cast(*p));        addresses_.Add(a);      }    }  }  virtual void VisitExternalReferences(Address* start, Address* end) {    for (Address* p = start; p < end; ++p) {      uint32_t code = reference_encoder_->Encode(*p);      CHECK(*p == NULL ? code == 0 : code != 0);      offsets_.Add(reinterpret_cast<Address>(p) - obj_address_);      addresses_.Add(reinterpret_cast<Address>(code));    }  }  virtual void VisitRuntimeEntry(RelocInfo* rinfo) {    Address target = rinfo->target_address();    uint32_t encoding = reference_encoder_->Encode(target);    CHECK(target == NULL ? encoding == 0 : encoding != 0);    offsets_.Add(reinterpret_cast<Address>(rinfo->pc()) - obj_address_);    addresses_.Add(reinterpret_cast<Address>(encoding));  }  void Update(Address start_address) {    for (int i = 0; i < offsets_.length(); i++) {      Address* p = reinterpret_cast<Address*>(start_address + offsets_[i]);      *p = addresses_[i];    }  } private:  Address obj_address_;  Serializer* serializer_;  ExternalReferenceEncoder* reference_encoder_;  List<int> offsets_;  List<Address> addresses_;};// Helper functions for a map of encoded heap object addresses.static uint32_t HeapObjectHash(HeapObject* key) {  return reinterpret_cast<uint32_t>(key) >> 2;}static bool MatchHeapObject(void* key1, void* key2) {  return key1 == key2;}Serializer::Serializer()  : global_handles_(4),    saved_addresses_(MatchHeapObject) {  root_ = true;  roots_ = 0;  objects_ = 0;  reference_encoder_ = NULL;  writer_ = new SnapshotWriter();  for (int i = 0; i <= LAST_SPACE; i++) {    allocator_[i] = new SimulatedHeapSpace();  }}Serializer::~Serializer() {  for (int i = 0; i <= LAST_SPACE; i++) {    delete allocator_[i];  }  if (reference_encoder_) delete reference_encoder_;  delete writer_;}bool Serializer::serialization_enabled_ = true;#ifdef DEBUGstatic const int kMaxTagLength = 32;void Serializer::Synchronize(const char* tag) {  if (FLAG_debug_serialization) {    int length = strlen(tag);    ASSERT(length <= kMaxTagLength);    writer_->PutC('S');    writer_->PutInt(length);    writer_->PutBytes(reinterpret_cast<const byte*>(tag), length);  }}#endifvoid Serializer::InitializeAllocators() {  for (int i = 0; i <= LAST_SPACE; i++) {    allocator_[i]->InitEmptyHeap(static_cast<AllocationSpace>(i));  }}bool Serializer::IsVisited(HeapObject *obj) {  HashMap::Entry* entry =    saved_addresses_.Lookup(obj, HeapObjectHash(obj), false);  return entry != NULL;}Address Serializer::GetSavedAddress(HeapObject *obj) {  HashMap::Entry* entry  = saved_addresses_.Lookup(obj, HeapObjectHash(obj), false);  ASSERT(entry != NULL);  return reinterpret_cast<Address>(entry->value);}void Serializer::SaveAddress(HeapObject* obj, Address addr) {  HashMap::Entry* entry =    saved_addresses_.Lookup(obj, HeapObjectHash(obj), true);  entry->value = addr;}void Serializer::Serialize() {  // No active threads.  CHECK_EQ(NULL, ThreadState::FirstInUse());  // No active or weak handles.  CHECK(HandleScopeImplementer::instance()->Blocks()->is_empty());  CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles());  // We need a counter function during serialization to resolve the  // references to counters in the code on the heap.  CHECK(StatsTable::HasCounterFunction());  CHECK(enabled());  InitializeAllocators();  reference_encoder_ = new ExternalReferenceEncoder();  PutHeader();  Heap::IterateRoots(this);  PutLog();  PutContextStack();  disable();}void Serializer::Finalize(char** str, int* len) {  writer_->GetString(str, len);}// Serialize objects by writing them into the stream.void Serializer::VisitPointers(Object** start, Object** end) {  bool root = root_;  root_ = false;  for (Object** p = start; p < end; ++p) {    bool serialized;    Address a = Encode(*p, &serialized);    if (root) {      roots_++;      // If the object was not just serialized,      // write its encoded address instead.      if (!serialized) PutEncodedAddress(a);    }  }  root_ = root;}class GlobalHandlesRetriever: public ObjectVisitor { public:  explicit GlobalHandlesRetriever(List<Object**>* handles)  : global_handles_(handles) {}  virtual void VisitPointers(Object** start, Object** end) {    for (; start != end; ++start) {      global_handles_->Add(start);    }  } private:  List<Object**>* global_handles_;};void Serializer::PutFlags() {  writer_->PutC('F');  List<char*>* argv = FlagList::argv();  writer_->PutInt(argv->length());  writer_->PutC('[');  for (int i = 0; i < argv->length(); i++) {    if (i > 0) writer_->PutC('|');    writer_->PutString((*argv)[i]);    DeleteArray((*argv)[i]);  }  writer_->PutC(']');  flags_end_ = writer_->length();  delete argv;}void Serializer::PutHeader() {  PutFlags();  writer_->PutC('D');#ifdef DEBUG  writer_->PutC(FLAG_debug_serialization ? '1' : '0');#else  writer_->PutC('0');#endif  // Write sizes of paged memory spaces. Allocate extra space for the old  // and code spaces, because objects in new space will be promoted to them.  writer_->PutC('S');  writer_->PutC('[');  writer_->PutInt(Heap::old_pointer_space()->Size() +                  Heap::new_space()->Size());  writer_->PutC('|');  writer_->PutInt(Heap::old_data_space()->Size() + Heap::new_space()->Size());  writer_->PutC('|');  writer_->PutInt(Heap::code_space()->Size() + Heap::new_space()->Size());  writer_->PutC('|');  writer_->PutInt(Heap::map_space()->Size());  writer_->PutC(']');  // Write global handles.  writer_->PutC('G');  writer_->PutC('[');  GlobalHandlesRetriever ghr(&global_handles_);  GlobalHandles::IterateRoots(&ghr);  for (int i = 0; i < global_handles_.length(); i++) {    writer_->PutC('N');  }  writer_->PutC(']');}void Serializer::PutLog() {#ifdef ENABLE_LOGGING_AND_PROFILING  if (FLAG_log_code) {    Logger::TearDown();    int pos = writer_->InsertC('L', flags_end_);    bool exists;    Vector<const char> log = ReadFile(FLAG_logfile, &exists);    writer_->InsertString(log.start(), pos);    log.Dispose();  }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -