| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 return; | 87 return; |
| 88 } | 88 } |
| 89 Add(address, type, id, name); | 89 Add(address, type, id, name); |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 void ExternalReferenceTable::Add(Address address, | 93 void ExternalReferenceTable::Add(Address address, |
| 94 TypeCode type, | 94 TypeCode type, |
| 95 uint16_t id, | 95 uint16_t id, |
| 96 const char* name) { | 96 const char* name) { |
| 97 ASSERT_NE(NULL, address); | 97 DCHECK_NE(NULL, address); |
| 98 ExternalReferenceEntry entry; | 98 ExternalReferenceEntry entry; |
| 99 entry.address = address; | 99 entry.address = address; |
| 100 entry.code = EncodeExternal(type, id); | 100 entry.code = EncodeExternal(type, id); |
| 101 entry.name = name; | 101 entry.name = name; |
| 102 ASSERT_NE(0, entry.code); | 102 DCHECK_NE(0, entry.code); |
| 103 refs_.Add(entry); | 103 refs_.Add(entry); |
| 104 if (id > max_id_[type]) max_id_[type] = id; | 104 if (id > max_id_[type]) max_id_[type] = id; |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 void ExternalReferenceTable::PopulateTable(Isolate* isolate) { | 108 void ExternalReferenceTable::PopulateTable(Isolate* isolate) { |
| 109 for (int type_code = 0; type_code < kTypeCodeCount; type_code++) { | 109 for (int type_code = 0; type_code < kTypeCodeCount; type_code++) { |
| 110 max_id_[type_code] = 0; | 110 max_id_[type_code] = 0; |
| 111 } | 111 } |
| 112 | 112 |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 ExternalReferenceTable* external_references = | 547 ExternalReferenceTable* external_references = |
| 548 ExternalReferenceTable::instance(isolate_); | 548 ExternalReferenceTable::instance(isolate_); |
| 549 for (int i = 0; i < external_references->size(); ++i) { | 549 for (int i = 0; i < external_references->size(); ++i) { |
| 550 Put(external_references->address(i), i); | 550 Put(external_references->address(i), i); |
| 551 } | 551 } |
| 552 } | 552 } |
| 553 | 553 |
| 554 | 554 |
| 555 uint32_t ExternalReferenceEncoder::Encode(Address key) const { | 555 uint32_t ExternalReferenceEncoder::Encode(Address key) const { |
| 556 int index = IndexOf(key); | 556 int index = IndexOf(key); |
| 557 ASSERT(key == NULL || index >= 0); | 557 DCHECK(key == NULL || index >= 0); |
| 558 return index >= 0 ? | 558 return index >= 0 ? |
| 559 ExternalReferenceTable::instance(isolate_)->code(index) : 0; | 559 ExternalReferenceTable::instance(isolate_)->code(index) : 0; |
| 560 } | 560 } |
| 561 | 561 |
| 562 | 562 |
| 563 const char* ExternalReferenceEncoder::NameOfAddress(Address key) const { | 563 const char* ExternalReferenceEncoder::NameOfAddress(Address key) const { |
| 564 int index = IndexOf(key); | 564 int index = IndexOf(key); |
| 565 return index >= 0 ? ExternalReferenceTable::instance(isolate_)->name(index) | 565 return index >= 0 ? ExternalReferenceTable::instance(isolate_)->name(index) |
| 566 : "<unknown>"; | 566 : "<unknown>"; |
| 567 } | 567 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 HashMap::Entry* entry = FindEntry(code_address); | 659 HashMap::Entry* entry = FindEntry(code_address); |
| 660 if (entry != NULL) { | 660 if (entry != NULL) { |
| 661 DeleteArray(static_cast<char*>(entry->value)); | 661 DeleteArray(static_cast<char*>(entry->value)); |
| 662 RemoveEntry(entry); | 662 RemoveEntry(entry); |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 | 665 |
| 666 void Move(Address from, Address to) { | 666 void Move(Address from, Address to) { |
| 667 if (from == to) return; | 667 if (from == to) return; |
| 668 HashMap::Entry* from_entry = FindEntry(from); | 668 HashMap::Entry* from_entry = FindEntry(from); |
| 669 ASSERT(from_entry != NULL); | 669 DCHECK(from_entry != NULL); |
| 670 void* value = from_entry->value; | 670 void* value = from_entry->value; |
| 671 RemoveEntry(from_entry); | 671 RemoveEntry(from_entry); |
| 672 HashMap::Entry* to_entry = FindOrCreateEntry(to); | 672 HashMap::Entry* to_entry = FindOrCreateEntry(to); |
| 673 ASSERT(to_entry->value == NULL); | 673 DCHECK(to_entry->value == NULL); |
| 674 to_entry->value = value; | 674 to_entry->value = value; |
| 675 } | 675 } |
| 676 | 676 |
| 677 private: | 677 private: |
| 678 static char* CopyName(const char* name, int name_size) { | 678 static char* CopyName(const char* name, int name_size) { |
| 679 char* result = NewArray<char>(name_size + 1); | 679 char* result = NewArray<char>(name_size + 1); |
| 680 for (int i = 0; i < name_size; ++i) { | 680 for (int i = 0; i < name_size; ++i) { |
| 681 char c = name[i]; | 681 char c = name[i]; |
| 682 if (c == '\0') c = ' '; | 682 if (c == '\0') c = ' '; |
| 683 result[i] = c; | 683 result[i] = c; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 PageIterator it(isolate_->heap()->code_space()); | 732 PageIterator it(isolate_->heap()->code_space()); |
| 733 while (it.has_next()) { | 733 while (it.has_next()) { |
| 734 Page* p = it.next(); | 734 Page* p = it.next(); |
| 735 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); | 735 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 | 738 |
| 739 | 739 |
| 740 void Deserializer::Deserialize(Isolate* isolate) { | 740 void Deserializer::Deserialize(Isolate* isolate) { |
| 741 isolate_ = isolate; | 741 isolate_ = isolate; |
| 742 ASSERT(isolate_ != NULL); | 742 DCHECK(isolate_ != NULL); |
| 743 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); | 743 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); |
| 744 // No active threads. | 744 // No active threads. |
| 745 ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); | 745 DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); |
| 746 // No active handles. | 746 // No active handles. |
| 747 ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); | 747 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); |
| 748 ASSERT_EQ(NULL, external_reference_decoder_); | 748 DCHECK_EQ(NULL, external_reference_decoder_); |
| 749 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); | 749 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
| 750 isolate_->heap()->IterateSmiRoots(this); | 750 isolate_->heap()->IterateSmiRoots(this); |
| 751 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 751 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
| 752 isolate_->heap()->RepairFreeListsAfterBoot(); | 752 isolate_->heap()->RepairFreeListsAfterBoot(); |
| 753 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); | 753 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); |
| 754 | 754 |
| 755 isolate_->heap()->set_native_contexts_list( | 755 isolate_->heap()->set_native_contexts_list( |
| 756 isolate_->heap()->undefined_value()); | 756 isolate_->heap()->undefined_value()); |
| 757 isolate_->heap()->set_array_buffers_list( | 757 isolate_->heap()->set_array_buffers_list( |
| 758 isolate_->heap()->undefined_value()); | 758 isolate_->heap()->undefined_value()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 778 | 778 |
| 779 // Issue code events for newly deserialized code objects. | 779 // Issue code events for newly deserialized code objects. |
| 780 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 780 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
| 781 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 781 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
| 782 } | 782 } |
| 783 | 783 |
| 784 | 784 |
| 785 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { | 785 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { |
| 786 isolate_ = isolate; | 786 isolate_ = isolate; |
| 787 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { | 787 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { |
| 788 ASSERT(reservations_[i] != kUninitializedReservation); | 788 DCHECK(reservations_[i] != kUninitializedReservation); |
| 789 } | 789 } |
| 790 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); | 790 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); |
| 791 if (external_reference_decoder_ == NULL) { | 791 if (external_reference_decoder_ == NULL) { |
| 792 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); | 792 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
| 793 } | 793 } |
| 794 | 794 |
| 795 DisallowHeapAllocation no_gc; | 795 DisallowHeapAllocation no_gc; |
| 796 | 796 |
| 797 // Keep track of the code space start and end pointers in case new | 797 // Keep track of the code space start and end pointers in case new |
| 798 // code objects were unserialized | 798 // code objects were unserialized |
| 799 OldSpace* code_space = isolate_->heap()->code_space(); | 799 OldSpace* code_space = isolate_->heap()->code_space(); |
| 800 Address start_address = code_space->top(); | 800 Address start_address = code_space->top(); |
| 801 VisitPointer(root); | 801 VisitPointer(root); |
| 802 | 802 |
| 803 // There's no code deserialized here. If this assert fires | 803 // There's no code deserialized here. If this assert fires |
| 804 // then that's changed and logging should be added to notify | 804 // then that's changed and logging should be added to notify |
| 805 // the profiler et al of the new code. | 805 // the profiler et al of the new code. |
| 806 CHECK_EQ(start_address, code_space->top()); | 806 CHECK_EQ(start_address, code_space->top()); |
| 807 } | 807 } |
| 808 | 808 |
| 809 | 809 |
| 810 Deserializer::~Deserializer() { | 810 Deserializer::~Deserializer() { |
| 811 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. | 811 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. |
| 812 // ASSERT(source_->AtEOF()); | 812 // DCHECK(source_->AtEOF()); |
| 813 if (external_reference_decoder_) { | 813 if (external_reference_decoder_) { |
| 814 delete external_reference_decoder_; | 814 delete external_reference_decoder_; |
| 815 external_reference_decoder_ = NULL; | 815 external_reference_decoder_ = NULL; |
| 816 } | 816 } |
| 817 if (attached_objects_) attached_objects_->Dispose(); | 817 if (attached_objects_) attached_objects_->Dispose(); |
| 818 } | 818 } |
| 819 | 819 |
| 820 | 820 |
| 821 // This is called on the roots. It is the driver of the deserialization | 821 // This is called on the roots. It is the driver of the deserialization |
| 822 // process. It is also called on the body of each function. | 822 // process. It is also called on the body of each function. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 835 } | 835 } |
| 836 isolate_->heap()->set_allocation_sites_list(site); | 836 isolate_->heap()->set_allocation_sites_list(site); |
| 837 } | 837 } |
| 838 | 838 |
| 839 | 839 |
| 840 // Used to insert a deserialized internalized string into the string table. | 840 // Used to insert a deserialized internalized string into the string table. |
| 841 class StringTableInsertionKey : public HashTableKey { | 841 class StringTableInsertionKey : public HashTableKey { |
| 842 public: | 842 public: |
| 843 explicit StringTableInsertionKey(String* string) | 843 explicit StringTableInsertionKey(String* string) |
| 844 : string_(string), hash_(HashForObject(string)) { | 844 : string_(string), hash_(HashForObject(string)) { |
| 845 ASSERT(string->IsInternalizedString()); | 845 DCHECK(string->IsInternalizedString()); |
| 846 } | 846 } |
| 847 | 847 |
| 848 virtual bool IsMatch(Object* string) { | 848 virtual bool IsMatch(Object* string) { |
| 849 // We know that all entries in a hash table had their hash keys created. | 849 // We know that all entries in a hash table had their hash keys created. |
| 850 // Use that knowledge to have fast failure. | 850 // Use that knowledge to have fast failure. |
| 851 if (hash_ != HashForObject(string)) return false; | 851 if (hash_ != HashForObject(string)) return false; |
| 852 // We want to compare the content of two internalized strings here. | 852 // We want to compare the content of two internalized strings here. |
| 853 return string_->SlowEquals(String::cast(string)); | 853 return string_->SlowEquals(String::cast(string)); |
| 854 } | 854 } |
| 855 | 855 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 // as a (weak) root. If this root is relocated correctly, | 917 // as a (weak) root. If this root is relocated correctly, |
| 918 // RelinkAllocationSite() isn't necessary. | 918 // RelinkAllocationSite() isn't necessary. |
| 919 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 919 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
| 920 | 920 |
| 921 // Fix up strings from serialized user code. | 921 // Fix up strings from serialized user code. |
| 922 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); | 922 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); |
| 923 | 923 |
| 924 *write_back = obj; | 924 *write_back = obj; |
| 925 #ifdef DEBUG | 925 #ifdef DEBUG |
| 926 bool is_codespace = (space_number == CODE_SPACE); | 926 bool is_codespace = (space_number == CODE_SPACE); |
| 927 ASSERT(obj->IsCode() == is_codespace); | 927 DCHECK(obj->IsCode() == is_codespace); |
| 928 #endif | 928 #endif |
| 929 } | 929 } |
| 930 | 930 |
| 931 void Deserializer::ReadChunk(Object** current, | 931 void Deserializer::ReadChunk(Object** current, |
| 932 Object** limit, | 932 Object** limit, |
| 933 int source_space, | 933 int source_space, |
| 934 Address current_object_address) { | 934 Address current_object_address) { |
| 935 Isolate* const isolate = isolate_; | 935 Isolate* const isolate = isolate_; |
| 936 // Write barrier support costs around 1% in startup time. In fact there | 936 // Write barrier support costs around 1% in startup time. In fact there |
| 937 // are no new space objects in current boot snapshots, so it's not needed, | 937 // are no new space objects in current boot snapshots, so it's not needed, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 int reference_id = source_->GetInt(); \ | 981 int reference_id = source_->GetInt(); \ |
| 982 Address address = external_reference_decoder_->Decode(reference_id); \ | 982 Address address = external_reference_decoder_->Decode(reference_id); \ |
| 983 new_object = reinterpret_cast<Object*>(address); \ | 983 new_object = reinterpret_cast<Object*>(address); \ |
| 984 } else if (where == kBackref) { \ | 984 } else if (where == kBackref) { \ |
| 985 emit_write_barrier = (space_number == NEW_SPACE); \ | 985 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 986 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 986 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 987 if (deserializing_user_code()) { \ | 987 if (deserializing_user_code()) { \ |
| 988 new_object = ProcessBackRefInSerializedCode(new_object); \ | 988 new_object = ProcessBackRefInSerializedCode(new_object); \ |
| 989 } \ | 989 } \ |
| 990 } else if (where == kBuiltin) { \ | 990 } else if (where == kBuiltin) { \ |
| 991 ASSERT(deserializing_user_code()); \ | 991 DCHECK(deserializing_user_code()); \ |
| 992 int builtin_id = source_->GetInt(); \ | 992 int builtin_id = source_->GetInt(); \ |
| 993 ASSERT_LE(0, builtin_id); \ | 993 DCHECK_LE(0, builtin_id); \ |
| 994 ASSERT_LT(builtin_id, Builtins::builtin_count); \ | 994 DCHECK_LT(builtin_id, Builtins::builtin_count); \ |
| 995 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 995 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
| 996 new_object = isolate->builtins()->builtin(name); \ | 996 new_object = isolate->builtins()->builtin(name); \ |
| 997 emit_write_barrier = false; \ | 997 emit_write_barrier = false; \ |
| 998 } else if (where == kAttachedReference) { \ | 998 } else if (where == kAttachedReference) { \ |
| 999 ASSERT(deserializing_user_code()); \ | 999 DCHECK(deserializing_user_code()); \ |
| 1000 int index = source_->GetInt(); \ | 1000 int index = source_->GetInt(); \ |
| 1001 new_object = attached_objects_->at(index); \ | 1001 new_object = attached_objects_->at(index); \ |
| 1002 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 1002 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
| 1003 } else { \ | 1003 } else { \ |
| 1004 ASSERT(where == kBackrefWithSkip); \ | 1004 DCHECK(where == kBackrefWithSkip); \ |
| 1005 int skip = source_->GetInt(); \ | 1005 int skip = source_->GetInt(); \ |
| 1006 current = reinterpret_cast<Object**>( \ | 1006 current = reinterpret_cast<Object**>( \ |
| 1007 reinterpret_cast<Address>(current) + skip); \ | 1007 reinterpret_cast<Address>(current) + skip); \ |
| 1008 emit_write_barrier = (space_number == NEW_SPACE); \ | 1008 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 1009 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 1009 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 1010 if (deserializing_user_code()) { \ | 1010 if (deserializing_user_code()) { \ |
| 1011 new_object = ProcessBackRefInSerializedCode(new_object); \ | 1011 new_object = ProcessBackRefInSerializedCode(new_object); \ |
| 1012 } \ | 1012 } \ |
| 1013 } \ | 1013 } \ |
| 1014 if (within == kInnerPointer) { \ | 1014 if (within == kInnerPointer) { \ |
| 1015 if (space_number != CODE_SPACE || new_object->IsCode()) { \ | 1015 if (space_number != CODE_SPACE || new_object->IsCode()) { \ |
| 1016 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ | 1016 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ |
| 1017 new_object = \ | 1017 new_object = \ |
| 1018 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ | 1018 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ |
| 1019 } else { \ | 1019 } else { \ |
| 1020 ASSERT(space_number == CODE_SPACE); \ | 1020 DCHECK(space_number == CODE_SPACE); \ |
| 1021 Cell* cell = Cell::cast(new_object); \ | 1021 Cell* cell = Cell::cast(new_object); \ |
| 1022 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ | 1022 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ |
| 1023 } \ | 1023 } \ |
| 1024 } \ | 1024 } \ |
| 1025 if (how == kFromCode) { \ | 1025 if (how == kFromCode) { \ |
| 1026 Address location_of_branch_data = reinterpret_cast<Address>(current); \ | 1026 Address location_of_branch_data = reinterpret_cast<Address>(current); \ |
| 1027 Assembler::deserialization_set_special_target_at( \ | 1027 Assembler::deserialization_set_special_target_at( \ |
| 1028 location_of_branch_data, \ | 1028 location_of_branch_data, \ |
| 1029 Code::cast(HeapObject::FromAddress(current_object_address)), \ | 1029 Code::cast(HeapObject::FromAddress(current_object_address)), \ |
| 1030 reinterpret_cast<Address>(new_object)); \ | 1030 reinterpret_cast<Address>(new_object)); \ |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 int size = source_->GetInt(); | 1125 int size = source_->GetInt(); |
| 1126 byte* raw_data_out = reinterpret_cast<byte*>(current); | 1126 byte* raw_data_out = reinterpret_cast<byte*>(current); |
| 1127 source_->CopyRaw(raw_data_out, size); | 1127 source_->CopyRaw(raw_data_out, size); |
| 1128 break; | 1128 break; |
| 1129 } | 1129 } |
| 1130 | 1130 |
| 1131 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) | 1131 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) |
| 1132 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { | 1132 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { |
| 1133 int root_id = RootArrayConstantFromByteCode(data); | 1133 int root_id = RootArrayConstantFromByteCode(data); |
| 1134 Object* object = isolate->heap()->roots_array_start()[root_id]; | 1134 Object* object = isolate->heap()->roots_array_start()[root_id]; |
| 1135 ASSERT(!isolate->heap()->InNewSpace(object)); | 1135 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1136 *current++ = object; | 1136 *current++ = object; |
| 1137 break; | 1137 break; |
| 1138 } | 1138 } |
| 1139 | 1139 |
| 1140 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) | 1140 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) |
| 1141 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { | 1141 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { |
| 1142 int root_id = RootArrayConstantFromByteCode(data); | 1142 int root_id = RootArrayConstantFromByteCode(data); |
| 1143 int skip = source_->GetInt(); | 1143 int skip = source_->GetInt(); |
| 1144 current = reinterpret_cast<Object**>( | 1144 current = reinterpret_cast<Object**>( |
| 1145 reinterpret_cast<intptr_t>(current) + skip); | 1145 reinterpret_cast<intptr_t>(current) + skip); |
| 1146 Object* object = isolate->heap()->roots_array_start()[root_id]; | 1146 Object* object = isolate->heap()->roots_array_start()[root_id]; |
| 1147 ASSERT(!isolate->heap()->InNewSpace(object)); | 1147 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1148 *current++ = object; | 1148 *current++ = object; |
| 1149 break; | 1149 break; |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 case kRepeat: { | 1152 case kRepeat: { |
| 1153 int repeats = source_->GetInt(); | 1153 int repeats = source_->GetInt(); |
| 1154 Object* object = current[-1]; | 1154 Object* object = current[-1]; |
| 1155 ASSERT(!isolate->heap()->InNewSpace(object)); | 1155 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1156 for (int i = 0; i < repeats; i++) current[i] = object; | 1156 for (int i = 0; i < repeats; i++) current[i] = object; |
| 1157 current += repeats; | 1157 current += repeats; |
| 1158 break; | 1158 break; |
| 1159 } | 1159 } |
| 1160 | 1160 |
| 1161 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == | 1161 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == |
| 1162 Heap::kOldSpaceRoots); | 1162 Heap::kOldSpaceRoots); |
| 1163 STATIC_ASSERT(kMaxRepeats == 13); | 1163 STATIC_ASSERT(kMaxRepeats == 13); |
| 1164 case kConstantRepeat: | 1164 case kConstantRepeat: |
| 1165 FOUR_CASES(kConstantRepeat + 1) | 1165 FOUR_CASES(kConstantRepeat + 1) |
| 1166 FOUR_CASES(kConstantRepeat + 5) | 1166 FOUR_CASES(kConstantRepeat + 5) |
| 1167 FOUR_CASES(kConstantRepeat + 9) { | 1167 FOUR_CASES(kConstantRepeat + 9) { |
| 1168 int repeats = RepeatsForCode(data); | 1168 int repeats = RepeatsForCode(data); |
| 1169 Object* object = current[-1]; | 1169 Object* object = current[-1]; |
| 1170 ASSERT(!isolate->heap()->InNewSpace(object)); | 1170 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1171 for (int i = 0; i < repeats; i++) current[i] = object; | 1171 for (int i = 0; i < repeats; i++) current[i] = object; |
| 1172 current += repeats; | 1172 current += repeats; |
| 1173 break; | 1173 break; |
| 1174 } | 1174 } |
| 1175 | 1175 |
| 1176 // Deserialize a new object and write a pointer to it to the current | 1176 // Deserialize a new object and write a pointer to it to the current |
| 1177 // object. | 1177 // object. |
| 1178 ALL_SPACES(kNewObject, kPlain, kStartOfObject) | 1178 ALL_SPACES(kNewObject, kPlain, kStartOfObject) |
| 1179 // Support for direct instruction pointers in functions. It's an inner | 1179 // Support for direct instruction pointers in functions. It's an inner |
| 1180 // pointer because it points at the entry point, not at the start of the | 1180 // pointer because it points at the entry point, not at the start of the |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 case kSynchronize: { | 1277 case kSynchronize: { |
| 1278 // If we get here then that indicates that you have a mismatch between | 1278 // If we get here then that indicates that you have a mismatch between |
| 1279 // the number of GC roots when serializing and deserializing. | 1279 // the number of GC roots when serializing and deserializing. |
| 1280 UNREACHABLE(); | 1280 UNREACHABLE(); |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 default: | 1283 default: |
| 1284 UNREACHABLE(); | 1284 UNREACHABLE(); |
| 1285 } | 1285 } |
| 1286 } | 1286 } |
| 1287 ASSERT_EQ(limit, current); | 1287 DCHECK_EQ(limit, current); |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 | 1290 |
| 1291 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1291 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
| 1292 : isolate_(isolate), | 1292 : isolate_(isolate), |
| 1293 sink_(sink), | 1293 sink_(sink), |
| 1294 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), | 1294 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
| 1295 root_index_wave_front_(0), | 1295 root_index_wave_front_(0), |
| 1296 code_address_map_(NULL) { | 1296 code_address_map_(NULL) { |
| 1297 // The serializer is meant to be used only to generate initial heap images | 1297 // The serializer is meant to be used only to generate initial heap images |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 } | 1399 } |
| 1400 | 1400 |
| 1401 // We didn't find the object in the cache. So we add it to the cache and | 1401 // We didn't find the object in the cache. So we add it to the cache and |
| 1402 // then visit the pointer so that it becomes part of the startup snapshot | 1402 // then visit the pointer so that it becomes part of the startup snapshot |
| 1403 // and we can refer to it from the partial snapshot. | 1403 // and we can refer to it from the partial snapshot. |
| 1404 int length = isolate->serialize_partial_snapshot_cache_length(); | 1404 int length = isolate->serialize_partial_snapshot_cache_length(); |
| 1405 isolate->PushToPartialSnapshotCache(heap_object); | 1405 isolate->PushToPartialSnapshotCache(heap_object); |
| 1406 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); | 1406 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); |
| 1407 // We don't recurse from the startup snapshot generator into the partial | 1407 // We don't recurse from the startup snapshot generator into the partial |
| 1408 // snapshot generator. | 1408 // snapshot generator. |
| 1409 ASSERT(length == isolate->serialize_partial_snapshot_cache_length() - 1); | 1409 DCHECK(length == isolate->serialize_partial_snapshot_cache_length() - 1); |
| 1410 return length; | 1410 return length; |
| 1411 } | 1411 } |
| 1412 | 1412 |
| 1413 | 1413 |
| 1414 int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) { | 1414 int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) { |
| 1415 Heap* heap = isolate()->heap(); | 1415 Heap* heap = isolate()->heap(); |
| 1416 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex; | 1416 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex; |
| 1417 for (int i = 0; i < root_index_wave_front_; i++) { | 1417 for (int i = 0; i < root_index_wave_front_; i++) { |
| 1418 Object* root = heap->roots_array_start()[i]; | 1418 Object* root = heap->roots_array_start()[i]; |
| 1419 if (!root->IsSmi() && root == heap_object) { | 1419 if (!root->IsSmi() && root == heap_object) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 Object* o, | 1541 Object* o, |
| 1542 HowToCode how_to_code, | 1542 HowToCode how_to_code, |
| 1543 WhereToPoint where_to_point, | 1543 WhereToPoint where_to_point, |
| 1544 int skip) { | 1544 int skip) { |
| 1545 CHECK(o->IsHeapObject()); | 1545 CHECK(o->IsHeapObject()); |
| 1546 HeapObject* heap_object = HeapObject::cast(o); | 1546 HeapObject* heap_object = HeapObject::cast(o); |
| 1547 | 1547 |
| 1548 if (heap_object->IsMap()) { | 1548 if (heap_object->IsMap()) { |
| 1549 // The code-caches link to context-specific code objects, which | 1549 // The code-caches link to context-specific code objects, which |
| 1550 // the startup and context serializes cannot currently handle. | 1550 // the startup and context serializes cannot currently handle. |
| 1551 ASSERT(Map::cast(heap_object)->code_cache() == | 1551 DCHECK(Map::cast(heap_object)->code_cache() == |
| 1552 heap_object->GetHeap()->empty_fixed_array()); | 1552 heap_object->GetHeap()->empty_fixed_array()); |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 int root_index; | 1555 int root_index; |
| 1556 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1556 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { |
| 1557 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1557 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); |
| 1558 return; | 1558 return; |
| 1559 } | 1559 } |
| 1560 | 1560 |
| 1561 if (ShouldBeInThePartialSnapshotCache(heap_object)) { | 1561 if (ShouldBeInThePartialSnapshotCache(heap_object)) { |
| 1562 if (skip != 0) { | 1562 if (skip != 0) { |
| 1563 sink_->Put(kSkip, "SkipFromSerializeObject"); | 1563 sink_->Put(kSkip, "SkipFromSerializeObject"); |
| 1564 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 1564 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
| 1565 } | 1565 } |
| 1566 | 1566 |
| 1567 int cache_index = PartialSnapshotCacheIndex(heap_object); | 1567 int cache_index = PartialSnapshotCacheIndex(heap_object); |
| 1568 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, | 1568 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, |
| 1569 "PartialSnapshotCache"); | 1569 "PartialSnapshotCache"); |
| 1570 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); | 1570 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); |
| 1571 return; | 1571 return; |
| 1572 } | 1572 } |
| 1573 | 1573 |
| 1574 // Pointers from the partial snapshot to the objects in the startup snapshot | 1574 // Pointers from the partial snapshot to the objects in the startup snapshot |
| 1575 // should go through the root array or through the partial snapshot cache. | 1575 // should go through the root array or through the partial snapshot cache. |
| 1576 // If this is not the case you may have to add something to the root array. | 1576 // If this is not the case you may have to add something to the root array. |
| 1577 ASSERT(!startup_serializer_->address_mapper()->IsMapped(heap_object)); | 1577 DCHECK(!startup_serializer_->address_mapper()->IsMapped(heap_object)); |
| 1578 // All the internalized strings that the partial snapshot needs should be | 1578 // All the internalized strings that the partial snapshot needs should be |
| 1579 // either in the root table or in the partial snapshot cache. | 1579 // either in the root table or in the partial snapshot cache. |
| 1580 ASSERT(!heap_object->IsInternalizedString()); | 1580 DCHECK(!heap_object->IsInternalizedString()); |
| 1581 | 1581 |
| 1582 if (address_mapper_.IsMapped(heap_object)) { | 1582 if (address_mapper_.IsMapped(heap_object)) { |
| 1583 int space = SpaceOfObject(heap_object); | 1583 int space = SpaceOfObject(heap_object); |
| 1584 int address = address_mapper_.MappedTo(heap_object); | 1584 int address = address_mapper_.MappedTo(heap_object); |
| 1585 SerializeReferenceToPreviousObject(space, | 1585 SerializeReferenceToPreviousObject(space, |
| 1586 address, | 1586 address, |
| 1587 how_to_code, | 1587 how_to_code, |
| 1588 where_to_point, | 1588 where_to_point, |
| 1589 skip); | 1589 skip); |
| 1590 } else { | 1590 } else { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 while (current < end && !(*current)->IsSmi()) { | 1645 while (current < end && !(*current)->IsSmi()) { |
| 1646 HeapObject* current_contents = HeapObject::cast(*current); | 1646 HeapObject* current_contents = HeapObject::cast(*current); |
| 1647 int root_index = serializer_->RootIndex(current_contents, kPlain); | 1647 int root_index = serializer_->RootIndex(current_contents, kPlain); |
| 1648 // Repeats are not subject to the write barrier so there are only some | 1648 // Repeats are not subject to the write barrier so there are only some |
| 1649 // objects that can be used in a repeat encoding. These are the early | 1649 // objects that can be used in a repeat encoding. These are the early |
| 1650 // ones in the root array that are never in new space. | 1650 // ones in the root array that are never in new space. |
| 1651 if (current != start && | 1651 if (current != start && |
| 1652 root_index != kInvalidRootIndex && | 1652 root_index != kInvalidRootIndex && |
| 1653 root_index < kRootArrayNumberOfConstantEncodings && | 1653 root_index < kRootArrayNumberOfConstantEncodings && |
| 1654 current_contents == current[-1]) { | 1654 current_contents == current[-1]) { |
| 1655 ASSERT(!serializer_->isolate()->heap()->InNewSpace(current_contents)); | 1655 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); |
| 1656 int repeat_count = 1; | 1656 int repeat_count = 1; |
| 1657 while (current < end - 1 && current[repeat_count] == current_contents) { | 1657 while (current < end - 1 && current[repeat_count] == current_contents) { |
| 1658 repeat_count++; | 1658 repeat_count++; |
| 1659 } | 1659 } |
| 1660 current += repeat_count; | 1660 current += repeat_count; |
| 1661 bytes_processed_so_far_ += repeat_count * kPointerSize; | 1661 bytes_processed_so_far_ += repeat_count * kPointerSize; |
| 1662 if (repeat_count > kMaxRepeats) { | 1662 if (repeat_count > kMaxRepeats) { |
| 1663 sink_->Put(kRepeat, "SerializeRepeats"); | 1663 sink_->Put(kRepeat, "SerializeRepeats"); |
| 1664 sink_->PutInt(repeat_count, "SerializeRepeats"); | 1664 sink_->PutInt(repeat_count, "SerializeRepeats"); |
| 1665 } else { | 1665 } else { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 int Serializer::ObjectSerializer::OutputRawData( | 1803 int Serializer::ObjectSerializer::OutputRawData( |
| 1804 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { | 1804 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { |
| 1805 Address object_start = object_->address(); | 1805 Address object_start = object_->address(); |
| 1806 int base = bytes_processed_so_far_; | 1806 int base = bytes_processed_so_far_; |
| 1807 int up_to_offset = static_cast<int>(up_to - object_start); | 1807 int up_to_offset = static_cast<int>(up_to - object_start); |
| 1808 int to_skip = up_to_offset - bytes_processed_so_far_; | 1808 int to_skip = up_to_offset - bytes_processed_so_far_; |
| 1809 int bytes_to_output = to_skip; | 1809 int bytes_to_output = to_skip; |
| 1810 bytes_processed_so_far_ += to_skip; | 1810 bytes_processed_so_far_ += to_skip; |
| 1811 // This assert will fail if the reloc info gives us the target_address_address | 1811 // This assert will fail if the reloc info gives us the target_address_address |
| 1812 // locations in a non-ascending order. Luckily that doesn't happen. | 1812 // locations in a non-ascending order. Luckily that doesn't happen. |
| 1813 ASSERT(to_skip >= 0); | 1813 DCHECK(to_skip >= 0); |
| 1814 bool outputting_code = false; | 1814 bool outputting_code = false; |
| 1815 if (to_skip != 0 && code_object_ && !code_has_been_output_) { | 1815 if (to_skip != 0 && code_object_ && !code_has_been_output_) { |
| 1816 // Output the code all at once and fix later. | 1816 // Output the code all at once and fix later. |
| 1817 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; | 1817 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; |
| 1818 outputting_code = true; | 1818 outputting_code = true; |
| 1819 code_has_been_output_ = true; | 1819 code_has_been_output_ = true; |
| 1820 } | 1820 } |
| 1821 if (bytes_to_output != 0 && | 1821 if (bytes_to_output != 0 && |
| 1822 (!code_object_ || outputting_code)) { | 1822 (!code_object_ || outputting_code)) { |
| 1823 #define RAW_CASE(index) \ | 1823 #define RAW_CASE(index) \ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 to_skip = 0; | 1856 to_skip = 0; |
| 1857 } | 1857 } |
| 1858 return to_skip; | 1858 return to_skip; |
| 1859 } | 1859 } |
| 1860 | 1860 |
| 1861 | 1861 |
| 1862 int Serializer::SpaceOfObject(HeapObject* object) { | 1862 int Serializer::SpaceOfObject(HeapObject* object) { |
| 1863 for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) { | 1863 for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) { |
| 1864 AllocationSpace s = static_cast<AllocationSpace>(i); | 1864 AllocationSpace s = static_cast<AllocationSpace>(i); |
| 1865 if (object->GetHeap()->InSpace(object, s)) { | 1865 if (object->GetHeap()->InSpace(object, s)) { |
| 1866 ASSERT(i < kNumberOfSpaces); | 1866 DCHECK(i < kNumberOfSpaces); |
| 1867 return i; | 1867 return i; |
| 1868 } | 1868 } |
| 1869 } | 1869 } |
| 1870 UNREACHABLE(); | 1870 UNREACHABLE(); |
| 1871 return 0; | 1871 return 0; |
| 1872 } | 1872 } |
| 1873 | 1873 |
| 1874 | 1874 |
| 1875 int Serializer::Allocate(int space, int size) { | 1875 int Serializer::Allocate(int space, int size) { |
| 1876 CHECK(space >= 0 && space < kNumberOfSpaces); | 1876 CHECK(space >= 0 && space < kNumberOfSpaces); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1921 } | 1921 } |
| 1922 | 1922 |
| 1923 | 1923 |
| 1924 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, | 1924 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, |
| 1925 WhereToPoint where_to_point, int skip) { | 1925 WhereToPoint where_to_point, int skip) { |
| 1926 CHECK(o->IsHeapObject()); | 1926 CHECK(o->IsHeapObject()); |
| 1927 HeapObject* heap_object = HeapObject::cast(o); | 1927 HeapObject* heap_object = HeapObject::cast(o); |
| 1928 | 1928 |
| 1929 // The code-caches link to context-specific code objects, which | 1929 // The code-caches link to context-specific code objects, which |
| 1930 // the startup and context serializes cannot currently handle. | 1930 // the startup and context serializes cannot currently handle. |
| 1931 ASSERT(!heap_object->IsMap() || | 1931 DCHECK(!heap_object->IsMap() || |
| 1932 Map::cast(heap_object)->code_cache() == | 1932 Map::cast(heap_object)->code_cache() == |
| 1933 heap_object->GetHeap()->empty_fixed_array()); | 1933 heap_object->GetHeap()->empty_fixed_array()); |
| 1934 | 1934 |
| 1935 int root_index; | 1935 int root_index; |
| 1936 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1936 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { |
| 1937 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1937 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); |
| 1938 return; | 1938 return; |
| 1939 } | 1939 } |
| 1940 | 1940 |
| 1941 // TODO(yangguo) wire up stubs from stub cache. | 1941 // TODO(yangguo) wire up stubs from stub cache. |
| 1942 // TODO(yangguo) wire up global object. | 1942 // TODO(yangguo) wire up global object. |
| 1943 // TODO(yangguo) We cannot deal with different hash seeds yet. | 1943 // TODO(yangguo) We cannot deal with different hash seeds yet. |
| 1944 ASSERT(!heap_object->IsHashTable()); | 1944 DCHECK(!heap_object->IsHashTable()); |
| 1945 | 1945 |
| 1946 if (address_mapper_.IsMapped(heap_object)) { | 1946 if (address_mapper_.IsMapped(heap_object)) { |
| 1947 int space = SpaceOfObject(heap_object); | 1947 int space = SpaceOfObject(heap_object); |
| 1948 int address = address_mapper_.MappedTo(heap_object); | 1948 int address = address_mapper_.MappedTo(heap_object); |
| 1949 SerializeReferenceToPreviousObject(space, address, how_to_code, | 1949 SerializeReferenceToPreviousObject(space, address, how_to_code, |
| 1950 where_to_point, skip); | 1950 where_to_point, skip); |
| 1951 return; | 1951 return; |
| 1952 } | 1952 } |
| 1953 | 1953 |
| 1954 if (heap_object->IsCode()) { | 1954 if (heap_object->IsCode()) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1983 } | 1983 } |
| 1984 | 1984 |
| 1985 | 1985 |
| 1986 void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code, | 1986 void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code, |
| 1987 WhereToPoint where_to_point, int skip) { | 1987 WhereToPoint where_to_point, int skip) { |
| 1988 if (skip != 0) { | 1988 if (skip != 0) { |
| 1989 sink_->Put(kSkip, "SkipFromSerializeBuiltin"); | 1989 sink_->Put(kSkip, "SkipFromSerializeBuiltin"); |
| 1990 sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin"); | 1990 sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin"); |
| 1991 } | 1991 } |
| 1992 | 1992 |
| 1993 ASSERT((how_to_code == kPlain && where_to_point == kStartOfObject) || | 1993 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || |
| 1994 (how_to_code == kFromCode && where_to_point == kInnerPointer)); | 1994 (how_to_code == kFromCode && where_to_point == kInnerPointer)); |
| 1995 int builtin_index = builtin->builtin_index(); | 1995 int builtin_index = builtin->builtin_index(); |
| 1996 ASSERT_LT(builtin_index, Builtins::builtin_count); | 1996 DCHECK_LT(builtin_index, Builtins::builtin_count); |
| 1997 ASSERT_LE(0, builtin_index); | 1997 DCHECK_LE(0, builtin_index); |
| 1998 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 1998 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
| 1999 sink_->PutInt(builtin_index, "builtin_index"); | 1999 sink_->PutInt(builtin_index, "builtin_index"); |
| 2000 } | 2000 } |
| 2001 | 2001 |
| 2002 | 2002 |
| 2003 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, | 2003 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, |
| 2004 WhereToPoint where_to_point, | 2004 WhereToPoint where_to_point, |
| 2005 int skip) { | 2005 int skip) { |
| 2006 if (skip != 0) { | 2006 if (skip != 0) { |
| 2007 sink_->Put(kSkip, "SkipFromSerializeSourceObject"); | 2007 sink_->Put(kSkip, "SkipFromSerializeSourceObject"); |
| 2008 sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject"); | 2008 sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject"); |
| 2009 } | 2009 } |
| 2010 | 2010 |
| 2011 ASSERT(how_to_code == kPlain && where_to_point == kStartOfObject); | 2011 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); |
| 2012 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); | 2012 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); |
| 2013 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); | 2013 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); |
| 2014 } | 2014 } |
| 2015 | 2015 |
| 2016 | 2016 |
| 2017 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate, | 2017 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate, |
| 2018 ScriptData* data, | 2018 ScriptData* data, |
| 2019 Handle<String> source) { | 2019 Handle<String> source) { |
| 2020 base::ElapsedTimer timer; | 2020 base::ElapsedTimer timer; |
| 2021 if (FLAG_profile_deserialization) timer.Start(); | 2021 if (FLAG_profile_deserialization) timer.Start(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2042 } | 2042 } |
| 2043 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate); | 2043 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate); |
| 2044 } | 2044 } |
| 2045 | 2045 |
| 2046 | 2046 |
| 2047 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) | 2047 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) |
| 2048 : owns_script_data_(true) { | 2048 : owns_script_data_(true) { |
| 2049 DisallowHeapAllocation no_gc; | 2049 DisallowHeapAllocation no_gc; |
| 2050 int data_length = payload->length() + kHeaderEntries * kIntSize; | 2050 int data_length = payload->length() + kHeaderEntries * kIntSize; |
| 2051 byte* data = NewArray<byte>(data_length); | 2051 byte* data = NewArray<byte>(data_length); |
| 2052 ASSERT(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2052 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
| 2053 CopyBytes(data + kHeaderEntries * kIntSize, payload->begin(), | 2053 CopyBytes(data + kHeaderEntries * kIntSize, payload->begin(), |
| 2054 static_cast<size_t>(payload->length())); | 2054 static_cast<size_t>(payload->length())); |
| 2055 script_data_ = new ScriptData(data, data_length); | 2055 script_data_ = new ScriptData(data, data_length); |
| 2056 script_data_->AcquireDataOwnership(); | 2056 script_data_->AcquireDataOwnership(); |
| 2057 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); | 2057 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
| 2058 STATIC_ASSERT(NEW_SPACE == 0); | 2058 STATIC_ASSERT(NEW_SPACE == 0); |
| 2059 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2059 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
| 2060 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); | 2060 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
| 2061 } | 2061 } |
| 2062 } | 2062 } |
| 2063 | 2063 |
| 2064 | 2064 |
| 2065 bool SerializedCodeData::IsSane(String* source) { | 2065 bool SerializedCodeData::IsSane(String* source) { |
| 2066 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && | 2066 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && |
| 2067 PayloadLength() >= SharedFunctionInfo::kSize; | 2067 PayloadLength() >= SharedFunctionInfo::kSize; |
| 2068 } | 2068 } |
| 2069 | 2069 |
| 2070 | 2070 |
| 2071 int SerializedCodeData::CheckSum(String* string) { | 2071 int SerializedCodeData::CheckSum(String* string) { |
| 2072 int checksum = Version::Hash(); | 2072 int checksum = Version::Hash(); |
| 2073 #ifdef DEBUG | 2073 #ifdef DEBUG |
| 2074 uint32_t seed = static_cast<uint32_t>(checksum); | 2074 uint32_t seed = static_cast<uint32_t>(checksum); |
| 2075 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2075 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
| 2076 #endif // DEBUG | 2076 #endif // DEBUG |
| 2077 return checksum; | 2077 return checksum; |
| 2078 } | 2078 } |
| 2079 } } // namespace v8::internal | 2079 } } // namespace v8::internal |
| OLD | NEW |