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 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 | 893 |
894 Object* write_back_obj = obj; | 894 Object* write_back_obj = obj; |
895 UnalignedCopy(write_back, &write_back_obj); | 895 UnalignedCopy(write_back, &write_back_obj); |
896 #ifdef DEBUG | 896 #ifdef DEBUG |
897 if (obj->IsCode()) { | 897 if (obj->IsCode()) { |
898 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); | 898 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
899 } else { | 899 } else { |
900 DCHECK(space_number != CODE_SPACE); | 900 DCHECK(space_number != CODE_SPACE); |
901 } | 901 } |
902 #endif | 902 #endif |
903 #if V8_TARGET_ARCH_PPC | 903 |
904 // If we're on a platform that uses function descriptors | 904 if (obj->IsCode()) { |
905 // these jump tables make use of RelocInfo::INTERNAL_REFERENCE. | 905 // Turn internal references encoded as offsets back to absolute addresses. |
906 // As the V8 serialization code doesn't handle that relocation type | 906 Code* code = Code::cast(obj); |
907 // we use this to fix up code that has function descriptors. | 907 Address entry = code->entry(); |
908 if (space_number == CODE_SPACE) { | 908 int mode_mask = RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE); |
909 Code* code = reinterpret_cast<Code*>(HeapObject::FromAddress(address)); | 909 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
910 for (RelocIterator it(code); !it.done(); it.next()) { | 910 RelocInfo* rinfo = it.rinfo(); |
911 RelocInfo::Mode rmode = it.rinfo()->rmode(); | 911 intptr_t offset = |
912 if (RelocInfo::IsInternalReference(rmode) || | 912 reinterpret_cast<intptr_t>(rinfo->target_internal_reference()); |
913 RelocInfo::IsInternalReferenceEncoded(rmode)) { | 913 DCHECK(0 <= offset && offset <= code->instruction_size()); |
914 Assembler::RelocateInternalReference(it.rinfo()->pc(), 0, | 914 rinfo->set_target_internal_reference(entry + offset); |
915 code->instruction_start(), rmode); | |
916 } | |
917 } | 915 } |
918 } | 916 } |
919 #endif | |
920 } | 917 } |
921 | 918 |
922 | 919 |
923 // We know the space requirements before deserialization and can | 920 // We know the space requirements before deserialization and can |
924 // pre-allocate that reserved space. During deserialization, all we need | 921 // pre-allocate that reserved space. During deserialization, all we need |
925 // to do is to bump up the pointer for each space in the reserved | 922 // to do is to bump up the pointer for each space in the reserved |
926 // space. This is also used for fixing back references. | 923 // space. This is also used for fixing back references. |
927 // We may have to split up the pre-allocation into several chunks | 924 // We may have to split up the pre-allocation into several chunks |
928 // because it would not fit onto a single page. We do not have to keep | 925 // because it would not fit onto a single page. We do not have to keep |
929 // track of when to move to the next chunk. An opcode will signal this. | 926 // track of when to move to the next chunk. An opcode will signal this. |
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 bytes_processed_so_far_ += kPointerSize; | 1962 bytes_processed_so_far_ += kPointerSize; |
1966 } | 1963 } |
1967 | 1964 |
1968 | 1965 |
1969 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { | 1966 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { |
1970 int skip = OutputRawData(rinfo->target_address_address(), | 1967 int skip = OutputRawData(rinfo->target_address_address(), |
1971 kCanReturnSkipInsteadOfSkipping); | 1968 kCanReturnSkipInsteadOfSkipping); |
1972 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 1969 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
1973 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 1970 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
1974 sink_->PutInt(skip, "SkipB4ExternalRef"); | 1971 sink_->PutInt(skip, "SkipB4ExternalRef"); |
1975 Address target = rinfo->target_reference(); | 1972 Address target = rinfo->target_external_reference(); |
1976 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 1973 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
1977 bytes_processed_so_far_ += rinfo->target_address_size(); | 1974 bytes_processed_so_far_ += rinfo->target_address_size(); |
1978 } | 1975 } |
1979 | 1976 |
1980 | 1977 |
1981 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 1978 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { |
1982 int skip = OutputRawData(rinfo->target_address_address(), | 1979 int skip = OutputRawData(rinfo->target_address_address(), |
1983 kCanReturnSkipInsteadOfSkipping); | 1980 kCanReturnSkipInsteadOfSkipping); |
1984 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 1981 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
1985 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 1982 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 } | 2039 } |
2043 // One of the strings in the natives cache should match the resource. We | 2040 // One of the strings in the natives cache should match the resource. We |
2044 // don't expect any other kinds of external strings here. | 2041 // don't expect any other kinds of external strings here. |
2045 UNREACHABLE(); | 2042 UNREACHABLE(); |
2046 } | 2043 } |
2047 | 2044 |
2048 | 2045 |
2049 Address Serializer::ObjectSerializer::PrepareCode() { | 2046 Address Serializer::ObjectSerializer::PrepareCode() { |
2050 // To make snapshots reproducible, we make a copy of the code object | 2047 // To make snapshots reproducible, we make a copy of the code object |
2051 // and wipe all pointers in the copy, which we then serialize. | 2048 // and wipe all pointers in the copy, which we then serialize. |
2052 Code* code = serializer_->CopyCode(Code::cast(object_)); | 2049 Code* original = Code::cast(object_); |
| 2050 Code* code = serializer_->CopyCode(original); |
2053 // Code age headers are not serializable. | 2051 // Code age headers are not serializable. |
2054 code->MakeYoung(serializer_->isolate()); | 2052 code->MakeYoung(serializer_->isolate()); |
2055 int mode_mask = | 2053 Address entry = original->entry(); |
2056 RelocInfo::kCodeTargetMask | | 2054 int mode_mask = RelocInfo::kCodeTargetMask | |
2057 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | 2055 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
2058 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | 2056 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
2059 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); | 2057 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | |
| 2058 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE); |
2060 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | 2059 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
2061 if (!(FLAG_enable_ool_constant_pool && it.rinfo()->IsInConstantPool())) { | 2060 RelocInfo* rinfo = it.rinfo(); |
2062 it.rinfo()->WipeOut(); | 2061 if (RelocInfo::IsInternalReference(rinfo->rmode())) { |
| 2062 // Convert internal references to relative offsets. |
| 2063 Address target = rinfo->target_internal_reference(); |
| 2064 intptr_t offset = target - entry; |
| 2065 DCHECK(0 <= offset && offset <= original->instruction_size()); |
| 2066 rinfo->set_target_internal_reference(reinterpret_cast<Address>(offset)); |
| 2067 } else if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) { |
| 2068 rinfo->WipeOut(); |
2063 } | 2069 } |
2064 } | 2070 } |
2065 // We need to wipe out the header fields *after* wiping out the | 2071 // We need to wipe out the header fields *after* wiping out the |
2066 // relocations, because some of these fields are needed for the latter. | 2072 // relocations, because some of these fields are needed for the latter. |
2067 code->WipeOutHeader(); | 2073 code->WipeOutHeader(); |
2068 return code->address(); | 2074 return code->address(); |
2069 } | 2075 } |
2070 | 2076 |
2071 | 2077 |
2072 int Serializer::ObjectSerializer::OutputRawData( | 2078 int Serializer::ObjectSerializer::OutputRawData( |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2652 DisallowHeapAllocation no_gc; | 2658 DisallowHeapAllocation no_gc; |
2653 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2659 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2654 SanityCheckResult r = scd->SanityCheck(source); | 2660 SanityCheckResult r = scd->SanityCheck(source); |
2655 if (r == CHECK_SUCCESS) return scd; | 2661 if (r == CHECK_SUCCESS) return scd; |
2656 cached_data->Reject(); | 2662 cached_data->Reject(); |
2657 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2663 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2658 delete scd; | 2664 delete scd; |
2659 return NULL; | 2665 return NULL; |
2660 } | 2666 } |
2661 } } // namespace v8::internal | 2667 } } // namespace v8::internal |
OLD | NEW |