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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
785 | 785 |
786 Object* write_back_obj = obj; | 786 Object* write_back_obj = obj; |
787 UnalignedCopy(write_back, &write_back_obj); | 787 UnalignedCopy(write_back, &write_back_obj); |
788 #ifdef DEBUG | 788 #ifdef DEBUG |
789 if (obj->IsCode()) { | 789 if (obj->IsCode()) { |
790 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); | 790 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
791 } else { | 791 } else { |
792 DCHECK(space_number != CODE_SPACE); | 792 DCHECK(space_number != CODE_SPACE); |
793 } | 793 } |
794 #endif | 794 #endif |
795 | |
796 if (obj->IsCode()) { | |
797 // Turn internal references encoded as offsets back to absolute addresses. | |
798 Code* code = Code::cast(obj); | |
799 Address entry = code->entry(); | |
800 int mode_mask = RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | | |
801 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); | |
802 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | |
803 RelocInfo* rinfo = it.rinfo(); | |
804 intptr_t offset = | |
805 reinterpret_cast<intptr_t>(rinfo->target_internal_reference()); | |
806 DCHECK(0 <= offset && offset <= code->instruction_size()); | |
807 rinfo->set_target_internal_reference(entry + offset); | |
808 } | |
809 } | |
810 } | 795 } |
811 | 796 |
812 | 797 |
813 // We know the space requirements before deserialization and can | 798 // We know the space requirements before deserialization and can |
814 // pre-allocate that reserved space. During deserialization, all we need | 799 // pre-allocate that reserved space. During deserialization, all we need |
815 // to do is to bump up the pointer for each space in the reserved | 800 // to do is to bump up the pointer for each space in the reserved |
816 // space. This is also used for fixing back references. | 801 // space. This is also used for fixing back references. |
817 // We may have to split up the pre-allocation into several chunks | 802 // We may have to split up the pre-allocation into several chunks |
818 // because it would not fit onto a single page. We do not have to keep | 803 // because it would not fit onto a single page. We do not have to keep |
819 // track of when to move to the next chunk. An opcode will signal this. | 804 // track of when to move to the next chunk. An opcode will signal this. |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1178 #undef CASE_BODY | 1163 #undef CASE_BODY |
1179 #undef ALL_SPACES | 1164 #undef ALL_SPACES |
1180 | 1165 |
1181 case kSkip: { | 1166 case kSkip: { |
1182 int size = source_.GetInt(); | 1167 int size = source_.GetInt(); |
1183 current = reinterpret_cast<Object**>( | 1168 current = reinterpret_cast<Object**>( |
1184 reinterpret_cast<intptr_t>(current) + size); | 1169 reinterpret_cast<intptr_t>(current) + size); |
1185 break; | 1170 break; |
1186 } | 1171 } |
1187 | 1172 |
1173 case kInternalReference: { | |
1174 int skip = source_.GetInt(); | |
1175 current = reinterpret_cast<Object**>( | |
1176 reinterpret_cast<Address>(current) + skip); | |
1177 int offset = source_.GetInt(); | |
1178 Code* code = | |
1179 Code::cast(HeapObject::FromAddress(current_object_address)); | |
1180 DCHECK(0 <= offset && offset <= code->instruction_size()); | |
1181 Address target = code->entry() + offset; | |
1182 Assembler::deserialization_set_target_internal_reference_at( | |
1183 reinterpret_cast<Address>(current), target); | |
1184 break; | |
1185 } | |
1186 | |
1188 case kNativesStringResource: { | 1187 case kNativesStringResource: { |
1189 DCHECK(!isolate_->heap()->deserialization_complete()); | 1188 DCHECK(!isolate_->heap()->deserialization_complete()); |
1190 int index = source_.Get(); | 1189 int index = source_.Get(); |
1191 Vector<const char> source_vector = Natives::GetScriptSource(index); | 1190 Vector<const char> source_vector = Natives::GetScriptSource(index); |
1192 NativesExternalStringResource* resource = | 1191 NativesExternalStringResource* resource = |
1193 new NativesExternalStringResource(source_vector.start(), | 1192 new NativesExternalStringResource(source_vector.start(), |
1194 source_vector.length()); | 1193 source_vector.length()); |
1195 Object* resource_obj = reinterpret_cast<Object*>(resource); | 1194 Object* resource_obj = reinterpret_cast<Object*>(resource); |
1196 UnalignedCopy(current++, &resource_obj); | 1195 UnalignedCopy(current++, &resource_obj); |
1197 break; | 1196 break; |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1865 kCanReturnSkipInsteadOfSkipping); | 1864 kCanReturnSkipInsteadOfSkipping); |
1866 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 1865 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
1867 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 1866 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
1868 sink_->PutInt(skip, "SkipB4ExternalRef"); | 1867 sink_->PutInt(skip, "SkipB4ExternalRef"); |
1869 Address target = rinfo->target_external_reference(); | 1868 Address target = rinfo->target_external_reference(); |
1870 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 1869 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
1871 bytes_processed_so_far_ += rinfo->target_address_size(); | 1870 bytes_processed_so_far_ += rinfo->target_address_size(); |
1872 } | 1871 } |
1873 | 1872 |
1874 | 1873 |
1874 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { | |
1875 DCHECK(code_object_); | |
Erik Corry
2015/03/17 15:31:16
I don't think you are allowed to use implicit bool
Yang
2015/03/18 09:37:20
code_object_ is a bool. I renamed it to is_code_ob
| |
1876 int skip = OutputRawData(rinfo->target_address_address(), | |
1877 kCanReturnSkipInsteadOfSkipping); | |
1878 sink_->Put(kInternalReference, "InternalRef"); | |
1879 sink_->PutInt(skip, "SkipB4InternalRef"); | |
1880 Address target = rinfo->target_internal_reference(); | |
1881 intptr_t offset = target - Code::cast(object_)->entry(); | |
1882 DCHECK(0 <= offset && offset <= Code::cast(object_)->instruction_size()); | |
1883 sink_->PutInt(static_cast<uintptr_t>(offset), "internal reference offset"); | |
1884 } | |
1885 | |
1886 | |
1875 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 1887 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { |
1876 int skip = OutputRawData(rinfo->target_address_address(), | 1888 int skip = OutputRawData(rinfo->target_address_address(), |
1877 kCanReturnSkipInsteadOfSkipping); | 1889 kCanReturnSkipInsteadOfSkipping); |
1878 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 1890 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
1879 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 1891 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
1880 sink_->PutInt(skip, "SkipB4ExternalRef"); | 1892 sink_->PutInt(skip, "SkipB4ExternalRef"); |
1881 Address target = rinfo->target_address(); | 1893 Address target = rinfo->target_address(); |
1882 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 1894 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
1883 bytes_processed_so_far_ += rinfo->target_address_size(); | 1895 bytes_processed_so_far_ += rinfo->target_address_size(); |
1884 } | 1896 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1940 } | 1952 } |
1941 | 1953 |
1942 | 1954 |
1943 Address Serializer::ObjectSerializer::PrepareCode() { | 1955 Address Serializer::ObjectSerializer::PrepareCode() { |
1944 // To make snapshots reproducible, we make a copy of the code object | 1956 // To make snapshots reproducible, we make a copy of the code object |
1945 // and wipe all pointers in the copy, which we then serialize. | 1957 // and wipe all pointers in the copy, which we then serialize. |
1946 Code* original = Code::cast(object_); | 1958 Code* original = Code::cast(object_); |
1947 Code* code = serializer_->CopyCode(original); | 1959 Code* code = serializer_->CopyCode(original); |
1948 // Code age headers are not serializable. | 1960 // Code age headers are not serializable. |
1949 code->MakeYoung(serializer_->isolate()); | 1961 code->MakeYoung(serializer_->isolate()); |
1950 Address entry = original->entry(); | |
1951 int mode_mask = RelocInfo::kCodeTargetMask | | 1962 int mode_mask = RelocInfo::kCodeTargetMask | |
1952 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | 1963 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
1953 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | 1964 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
1954 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | | 1965 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | |
1955 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | | 1966 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | |
1956 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); | 1967 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); |
1957 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | 1968 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
1958 RelocInfo* rinfo = it.rinfo(); | 1969 RelocInfo* rinfo = it.rinfo(); |
1959 RelocInfo::Mode rmode = rinfo->rmode(); | 1970 if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) { |
Erik Corry
2015/03/17 15:31:16
If you don't wipe internal offsets, will snapshots
Yang
2015/03/18 09:37:20
This is necessary to make the snapshot reproducibl
| |
1960 if (RelocInfo::IsInternalReference(rmode) || | |
1961 RelocInfo::IsInternalReferenceEncoded(rmode)) { | |
1962 // Convert internal references to relative offsets. | |
1963 Address target = rinfo->target_internal_reference(); | |
1964 intptr_t offset = target - entry; | |
1965 DCHECK(0 <= offset && offset <= original->instruction_size()); | |
1966 rinfo->set_target_internal_reference(reinterpret_cast<Address>(offset)); | |
1967 } else if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) { | |
1968 rinfo->WipeOut(); | 1971 rinfo->WipeOut(); |
1969 } | 1972 } |
1970 } | 1973 } |
1971 // We need to wipe out the header fields *after* wiping out the | 1974 // We need to wipe out the header fields *after* wiping out the |
1972 // relocations, because some of these fields are needed for the latter. | 1975 // relocations, because some of these fields are needed for the latter. |
1973 code->WipeOutHeader(); | 1976 code->WipeOutHeader(); |
1974 return code->address(); | 1977 return code->address(); |
1975 } | 1978 } |
1976 | 1979 |
1977 | 1980 |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2560 DisallowHeapAllocation no_gc; | 2563 DisallowHeapAllocation no_gc; |
2561 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2564 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2562 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2565 SanityCheckResult r = scd->SanityCheck(isolate, source); |
2563 if (r == CHECK_SUCCESS) return scd; | 2566 if (r == CHECK_SUCCESS) return scd; |
2564 cached_data->Reject(); | 2567 cached_data->Reject(); |
2565 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2568 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2566 delete scd; | 2569 delete scd; |
2567 return NULL; | 2570 return NULL; |
2568 } | 2571 } |
2569 } } // namespace v8::internal | 2572 } } // namespace v8::internal |
OLD | NEW |