| 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 |