Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/serialize.cc

Issue 1005183006: Serializer: serialize internal references via object visitor. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix compilation Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/serialize.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 773 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
774 774
775 // Fix up strings from serialized user code. 775 // Fix up strings from serialized user code.
776 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 776 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
777 777
778 Object* write_back_obj = obj; 778 Object* write_back_obj = obj;
779 UnalignedCopy(write_back, &write_back_obj); 779 UnalignedCopy(write_back, &write_back_obj);
780 #ifdef DEBUG 780 #ifdef DEBUG
781 if (obj->IsCode()) { 781 if (obj->IsCode()) {
782 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); 782 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
783 #ifdef VERIFY_HEAP
784 obj->ObjectVerify();
785 #endif // VERIFY_HEAP
783 } else { 786 } else {
784 DCHECK(space_number != CODE_SPACE); 787 DCHECK(space_number != CODE_SPACE);
785 } 788 }
786 #endif 789 #endif // DEBUG
787
788 if (obj->IsCode()) {
789 // Turn internal references encoded as offsets back to absolute addresses.
790 Code* code = Code::cast(obj);
791 Address entry = code->entry();
792 int mode_mask = RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
793 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
794 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
795 RelocInfo* rinfo = it.rinfo();
796 intptr_t offset =
797 reinterpret_cast<intptr_t>(rinfo->target_internal_reference());
798 DCHECK(0 <= offset && offset <= code->instruction_size());
799 rinfo->set_target_internal_reference(entry + offset);
800 }
801 }
802 } 790 }
803 791
804 792
805 // We know the space requirements before deserialization and can 793 // We know the space requirements before deserialization and can
806 // pre-allocate that reserved space. During deserialization, all we need 794 // pre-allocate that reserved space. During deserialization, all we need
807 // to do is to bump up the pointer for each space in the reserved 795 // to do is to bump up the pointer for each space in the reserved
808 // space. This is also used for fixing back references. 796 // space. This is also used for fixing back references.
809 // We may have to split up the pre-allocation into several chunks 797 // We may have to split up the pre-allocation into several chunks
810 // because it would not fit onto a single page. We do not have to keep 798 // because it would not fit onto a single page. We do not have to keep
811 // track of when to move to the next chunk. An opcode will signal this. 799 // track of when to move to the next chunk. An opcode will signal this.
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 #undef CASE_BODY 1153 #undef CASE_BODY
1166 #undef ALL_SPACES 1154 #undef ALL_SPACES
1167 1155
1168 case kSkip: { 1156 case kSkip: {
1169 int size = source_.GetInt(); 1157 int size = source_.GetInt();
1170 current = reinterpret_cast<Object**>( 1158 current = reinterpret_cast<Object**>(
1171 reinterpret_cast<intptr_t>(current) + size); 1159 reinterpret_cast<intptr_t>(current) + size);
1172 break; 1160 break;
1173 } 1161 }
1174 1162
1163 case kInternalReference: {
1164 // Internal reference address is not encoded via skip, but by offset
1165 // from code entry.
1166 int pc_offset = source_.GetInt();
1167 int target_offset = source_.GetInt();
1168 Code* code =
1169 Code::cast(HeapObject::FromAddress(current_object_address));
1170 DCHECK(0 <= pc_offset && pc_offset <= code->instruction_size());
1171 DCHECK(0 <= target_offset && target_offset <= code->instruction_size());
1172 Address pc = code->entry() + pc_offset;
1173 Address target = code->entry() + target_offset;
1174 Assembler::deserialization_set_target_internal_reference_at(pc, target);
1175 break;
1176 }
1177
1175 case kNativesStringResource: { 1178 case kNativesStringResource: {
1176 DCHECK(!isolate_->heap()->deserialization_complete()); 1179 DCHECK(!isolate_->heap()->deserialization_complete());
1177 int index = source_.Get(); 1180 int index = source_.Get();
1178 Vector<const char> source_vector = Natives::GetScriptSource(index); 1181 Vector<const char> source_vector = Natives::GetScriptSource(index);
1179 NativesExternalStringResource* resource = 1182 NativesExternalStringResource* resource =
1180 new NativesExternalStringResource(source_vector.start(), 1183 new NativesExternalStringResource(source_vector.start(),
1181 source_vector.length()); 1184 source_vector.length());
1182 Object* resource_obj = reinterpret_cast<Object*>(resource); 1185 Object* resource_obj = reinterpret_cast<Object*>(resource);
1183 UnalignedCopy(current++, &resource_obj); 1186 UnalignedCopy(current++, &resource_obj);
1184 break; 1187 break;
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 kCanReturnSkipInsteadOfSkipping); 1855 kCanReturnSkipInsteadOfSkipping);
1853 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; 1856 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
1854 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); 1857 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
1855 sink_->PutInt(skip, "SkipB4ExternalRef"); 1858 sink_->PutInt(skip, "SkipB4ExternalRef");
1856 Address target = rinfo->target_external_reference(); 1859 Address target = rinfo->target_external_reference();
1857 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); 1860 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
1858 bytes_processed_so_far_ += rinfo->target_address_size(); 1861 bytes_processed_so_far_ += rinfo->target_address_size();
1859 } 1862 }
1860 1863
1861 1864
1865 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) {
1866 // We can only reference to internal references of code that has been output.
1867 DCHECK(is_code_object_ && code_has_been_output_);
1868 // We do not use skip from last patched pc to find the pc to patch, since
1869 // target_address_address may not return addresses in ascending order when
1870 // used for internal references. External references may be stored at the
1871 // end of the code in the constant pool, whereas internal references are
1872 // inline. That would cause the skip to be negative. Instead, we store the
1873 // offset from code entry.
1874 Address entry = Code::cast(object_)->entry();
1875 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry;
1876 intptr_t target_offset = rinfo->target_internal_reference() - entry;
1877 DCHECK(0 <= pc_offset &&
1878 pc_offset <= Code::cast(object_)->instruction_size());
1879 DCHECK(0 <= target_offset &&
1880 target_offset <= Code::cast(object_)->instruction_size());
1881 sink_->Put(kInternalReference, "InternalRef");
1882 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address");
1883 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value");
1884 }
1885
1886
1862 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { 1887 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
1863 int skip = OutputRawData(rinfo->target_address_address(), 1888 int skip = OutputRawData(rinfo->target_address_address(),
1864 kCanReturnSkipInsteadOfSkipping); 1889 kCanReturnSkipInsteadOfSkipping);
1865 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; 1890 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
1866 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); 1891 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
1867 sink_->PutInt(skip, "SkipB4ExternalRef"); 1892 sink_->PutInt(skip, "SkipB4ExternalRef");
1868 Address target = rinfo->target_address(); 1893 Address target = rinfo->target_address();
1869 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); 1894 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
1870 bytes_processed_so_far_ += rinfo->target_address_size(); 1895 bytes_processed_so_far_ += rinfo->target_address_size();
1871 } 1896 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 } 1952 }
1928 1953
1929 1954
1930 Address Serializer::ObjectSerializer::PrepareCode() { 1955 Address Serializer::ObjectSerializer::PrepareCode() {
1931 // 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
1932 // and wipe all pointers in the copy, which we then serialize. 1957 // and wipe all pointers in the copy, which we then serialize.
1933 Code* original = Code::cast(object_); 1958 Code* original = Code::cast(object_);
1934 Code* code = serializer_->CopyCode(original); 1959 Code* code = serializer_->CopyCode(original);
1935 // Code age headers are not serializable. 1960 // Code age headers are not serializable.
1936 code->MakeYoung(serializer_->isolate()); 1961 code->MakeYoung(serializer_->isolate());
1937 Address entry = original->entry();
1938 int mode_mask = RelocInfo::kCodeTargetMask | 1962 int mode_mask = RelocInfo::kCodeTargetMask |
1939 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 1963 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
1940 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 1964 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
1941 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | 1965 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
1942 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | 1966 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
1943 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); 1967 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
1944 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { 1968 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
1945 RelocInfo* rinfo = it.rinfo(); 1969 RelocInfo* rinfo = it.rinfo();
1946 RelocInfo::Mode rmode = rinfo->rmode(); 1970 if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) {
1947 if (RelocInfo::IsInternalReference(rmode) ||
1948 RelocInfo::IsInternalReferenceEncoded(rmode)) {
1949 // Convert internal references to relative offsets.
1950 Address target = rinfo->target_internal_reference();
1951 intptr_t offset = target - entry;
1952 DCHECK(0 <= offset && offset <= original->instruction_size());
1953 rinfo->set_target_internal_reference(reinterpret_cast<Address>(offset));
1954 } else if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) {
1955 rinfo->WipeOut(); 1971 rinfo->WipeOut();
1956 } 1972 }
1957 } 1973 }
1958 // 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
1959 // relocations, because some of these fields are needed for the latter. 1975 // relocations, because some of these fields are needed for the latter.
1960 code->WipeOutHeader(); 1976 code->WipeOutHeader();
1961 return code->address(); 1977 return code->address();
1962 } 1978 }
1963 1979
1964 1980
1965 int Serializer::ObjectSerializer::OutputRawData( 1981 int Serializer::ObjectSerializer::OutputRawData(
1966 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { 1982 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) {
1967 Address object_start = object_->address(); 1983 Address object_start = object_->address();
1968 int base = bytes_processed_so_far_; 1984 int base = bytes_processed_so_far_;
1969 int up_to_offset = static_cast<int>(up_to - object_start); 1985 int up_to_offset = static_cast<int>(up_to - object_start);
1970 int to_skip = up_to_offset - bytes_processed_so_far_; 1986 int to_skip = up_to_offset - bytes_processed_so_far_;
1971 int bytes_to_output = to_skip; 1987 int bytes_to_output = to_skip;
1972 bytes_processed_so_far_ += to_skip; 1988 bytes_processed_so_far_ += to_skip;
1973 // This assert will fail if the reloc info gives us the target_address_address 1989 // This assert will fail if the reloc info gives us the target_address_address
1974 // locations in a non-ascending order. Luckily that doesn't happen. 1990 // locations in a non-ascending order. Luckily that doesn't happen.
1975 DCHECK(to_skip >= 0); 1991 DCHECK(to_skip >= 0);
1976 bool outputting_code = false; 1992 bool outputting_code = false;
1977 if (to_skip != 0 && code_object_ && !code_has_been_output_) { 1993 if (to_skip != 0 && is_code_object_ && !code_has_been_output_) {
1978 // Output the code all at once and fix later. 1994 // Output the code all at once and fix later.
1979 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; 1995 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_;
1980 outputting_code = true; 1996 outputting_code = true;
1981 code_has_been_output_ = true; 1997 code_has_been_output_ = true;
1982 } 1998 }
1983 if (bytes_to_output != 0 && 1999 if (bytes_to_output != 0 && (!is_code_object_ || outputting_code)) {
1984 (!code_object_ || outputting_code)) {
1985 #define RAW_CASE(index) \ 2000 #define RAW_CASE(index) \
1986 if (!outputting_code && bytes_to_output == index * kPointerSize && \ 2001 if (!outputting_code && bytes_to_output == index * kPointerSize && \
1987 index * kPointerSize == to_skip) { \ 2002 index * kPointerSize == to_skip) { \
1988 sink_->PutSection(kRawData + index, "RawDataFixed"); \ 2003 sink_->PutSection(kRawData + index, "RawDataFixed"); \
1989 to_skip = 0; /* This insn already skips. */ \ 2004 to_skip = 0; /* This insn already skips. */ \
1990 } else /* NOLINT */ 2005 } else /* NOLINT */
1991 COMMON_RAW_LENGTHS(RAW_CASE) 2006 COMMON_RAW_LENGTHS(RAW_CASE)
1992 #undef RAW_CASE 2007 #undef RAW_CASE
1993 { /* NOLINT */ 2008 { /* NOLINT */
1994 // We always end up here if we are outputting the code of a code object. 2009 // We always end up here if we are outputting the code of a code object.
1995 sink_->Put(kRawData, "RawData"); 2010 sink_->Put(kRawData, "RawData");
1996 sink_->PutInt(bytes_to_output, "length"); 2011 sink_->PutInt(bytes_to_output, "length");
1997 } 2012 }
1998 2013
1999 if (code_object_) object_start = PrepareCode(); 2014 if (is_code_object_) object_start = PrepareCode();
2000 2015
2001 const char* description = code_object_ ? "Code" : "Byte"; 2016 const char* description = is_code_object_ ? "Code" : "Byte";
2002 #ifdef MEMORY_SANITIZER 2017 #ifdef MEMORY_SANITIZER
2003 // Object sizes are usually rounded up with uninitialized padding space. 2018 // Object sizes are usually rounded up with uninitialized padding space.
2004 MSAN_MEMORY_IS_INITIALIZED(object_start + base, bytes_to_output); 2019 MSAN_MEMORY_IS_INITIALIZED(object_start + base, bytes_to_output);
2005 #endif // MEMORY_SANITIZER 2020 #endif // MEMORY_SANITIZER
2006 sink_->PutRaw(object_start + base, bytes_to_output, description); 2021 sink_->PutRaw(object_start + base, bytes_to_output, description);
2007 } 2022 }
2008 if (to_skip != 0 && return_skip == kIgnoringReturn) { 2023 if (to_skip != 0 && return_skip == kIgnoringReturn) {
2009 sink_->Put(kSkip, "Skip"); 2024 sink_->Put(kSkip, "Skip");
2010 sink_->PutInt(to_skip, "SkipDistance"); 2025 sink_->PutInt(to_skip, "SkipDistance");
2011 to_skip = 0; 2026 to_skip = 0;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 if (isolate->logger()->is_logging_code_events() || 2330 if (isolate->logger()->is_logging_code_events() ||
2316 isolate->cpu_profiler()->is_profiling()) { 2331 isolate->cpu_profiler()->is_profiling()) {
2317 String* name = isolate->heap()->empty_string(); 2332 String* name = isolate->heap()->empty_string();
2318 if (result->script()->IsScript()) { 2333 if (result->script()->IsScript()) {
2319 Script* script = Script::cast(result->script()); 2334 Script* script = Script::cast(result->script());
2320 if (script->name()->IsString()) name = String::cast(script->name()); 2335 if (script->name()->IsString()) name = String::cast(script->name());
2321 } 2336 }
2322 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(), 2337 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(),
2323 *result, NULL, name); 2338 *result, NULL, name);
2324 } 2339 }
2325
2326 return scope.CloseAndEscape(result); 2340 return scope.CloseAndEscape(result);
2327 } 2341 }
2328 2342
2329 2343
2330 void SerializedData::AllocateData(int size) { 2344 void SerializedData::AllocateData(int size) {
2331 DCHECK(!owns_data_); 2345 DCHECK(!owns_data_);
2332 data_ = NewArray<byte>(size); 2346 data_ = NewArray<byte>(size);
2333 size_ = size; 2347 size_ = size;
2334 owns_data_ = true; 2348 owns_data_ = true;
2335 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment)); 2349 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 DisallowHeapAllocation no_gc; 2561 DisallowHeapAllocation no_gc;
2548 SerializedCodeData* scd = new SerializedCodeData(cached_data); 2562 SerializedCodeData* scd = new SerializedCodeData(cached_data);
2549 SanityCheckResult r = scd->SanityCheck(isolate, source); 2563 SanityCheckResult r = scd->SanityCheck(isolate, source);
2550 if (r == CHECK_SUCCESS) return scd; 2564 if (r == CHECK_SUCCESS) return scd;
2551 cached_data->Reject(); 2565 cached_data->Reject();
2552 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); 2566 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r);
2553 delete scd; 2567 delete scd;
2554 return NULL; 2568 return NULL;
2555 } 2569 }
2556 } } // namespace v8::internal 2570 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698