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

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: platform ports 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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 781 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
782 782
783 // Fix up strings from serialized user code. 783 // Fix up strings from serialized user code.
784 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 784 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
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 #ifdef VERIFY_HEAP
792 obj->ObjectVerify();
793 #endif // VERIFY_HEAP
791 } else { 794 } else {
792 DCHECK(space_number != CODE_SPACE); 795 DCHECK(space_number != CODE_SPACE);
793 } 796 }
794 #endif 797 #endif // DEBUG
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 } 798 }
811 799
812 800
813 // We know the space requirements before deserialization and can 801 // We know the space requirements before deserialization and can
814 // pre-allocate that reserved space. During deserialization, all we need 802 // 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 803 // to do is to bump up the pointer for each space in the reserved
816 // space. This is also used for fixing back references. 804 // space. This is also used for fixing back references.
817 // We may have to split up the pre-allocation into several chunks 805 // 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 806 // 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. 807 // 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
1178 #undef CASE_BODY 1166 #undef CASE_BODY
1179 #undef ALL_SPACES 1167 #undef ALL_SPACES
1180 1168
1181 case kSkip: { 1169 case kSkip: {
1182 int size = source_.GetInt(); 1170 int size = source_.GetInt();
1183 current = reinterpret_cast<Object**>( 1171 current = reinterpret_cast<Object**>(
1184 reinterpret_cast<intptr_t>(current) + size); 1172 reinterpret_cast<intptr_t>(current) + size);
1185 break; 1173 break;
1186 } 1174 }
1187 1175
1176 case kInternalReference: {
1177 // Internal reference address is not encoded via skip, but by offset
1178 // from code entry.
1179 int pc_offset = source_.GetInt();
1180 int target_offset = source_.GetInt();
1181 Code* code =
1182 Code::cast(HeapObject::FromAddress(current_object_address));
1183 DCHECK(0 <= pc_offset && pc_offset <= code->instruction_size());
1184 DCHECK(0 <= target_offset && target_offset <= code->instruction_size());
1185 Address pc = code->entry() + pc_offset;
1186 Address target = code->entry() + target_offset;
1187 Assembler::deserialization_set_target_internal_reference_at(pc, target);
1188 break;
1189 }
1190
1188 case kNativesStringResource: { 1191 case kNativesStringResource: {
1189 DCHECK(!isolate_->heap()->deserialization_complete()); 1192 DCHECK(!isolate_->heap()->deserialization_complete());
1190 int index = source_.Get(); 1193 int index = source_.Get();
1191 Vector<const char> source_vector = Natives::GetScriptSource(index); 1194 Vector<const char> source_vector = Natives::GetScriptSource(index);
1192 NativesExternalStringResource* resource = 1195 NativesExternalStringResource* resource =
1193 new NativesExternalStringResource(source_vector.start(), 1196 new NativesExternalStringResource(source_vector.start(),
1194 source_vector.length()); 1197 source_vector.length());
1195 Object* resource_obj = reinterpret_cast<Object*>(resource); 1198 Object* resource_obj = reinterpret_cast<Object*>(resource);
1196 UnalignedCopy(current++, &resource_obj); 1199 UnalignedCopy(current++, &resource_obj);
1197 break; 1200 break;
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 kCanReturnSkipInsteadOfSkipping); 1868 kCanReturnSkipInsteadOfSkipping);
1866 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; 1869 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
1867 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); 1870 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
1868 sink_->PutInt(skip, "SkipB4ExternalRef"); 1871 sink_->PutInt(skip, "SkipB4ExternalRef");
1869 Address target = rinfo->target_external_reference(); 1872 Address target = rinfo->target_external_reference();
1870 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); 1873 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
1871 bytes_processed_so_far_ += rinfo->target_address_size(); 1874 bytes_processed_so_far_ += rinfo->target_address_size();
1872 } 1875 }
1873 1876
1874 1877
1878 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) {
1879 DCHECK(code_object_ && code_has_been_output_);
1880 // We do not use skip from last patched pc to find the pc to patch, since
1881 // target_address_address may not return addresses in ascending order when
1882 // used for internal references. External references may be stored at the
1883 // end of the code in the constant pool, whereas internal references are
1884 // inline. That would cause the skip to be negative. Instead, we store the
1885 // offset from code entry.
1886 Address entry = Code::cast(object_)->entry();
1887 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry;
1888 intptr_t target_offset = rinfo->target_internal_reference() - entry;
1889 DCHECK(0 <= pc_offset &&
1890 pc_offset <= Code::cast(object_)->instruction_size());
1891 DCHECK(0 <= target_offset &&
1892 target_offset <= Code::cast(object_)->instruction_size());
1893 sink_->Put(kInternalReference, "InternalRef");
1894 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address");
1895 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value");
1896 }
1897
1898
1875 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { 1899 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
1876 int skip = OutputRawData(rinfo->target_address_address(), 1900 int skip = OutputRawData(rinfo->target_address_address(),
1877 kCanReturnSkipInsteadOfSkipping); 1901 kCanReturnSkipInsteadOfSkipping);
1878 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; 1902 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
1879 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); 1903 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef");
1880 sink_->PutInt(skip, "SkipB4ExternalRef"); 1904 sink_->PutInt(skip, "SkipB4ExternalRef");
1881 Address target = rinfo->target_address(); 1905 Address target = rinfo->target_address();
1882 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); 1906 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id");
1883 bytes_processed_so_far_ += rinfo->target_address_size(); 1907 bytes_processed_so_far_ += rinfo->target_address_size();
1884 } 1908 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 } 1964 }
1941 1965
1942 1966
1943 Address Serializer::ObjectSerializer::PrepareCode() { 1967 Address Serializer::ObjectSerializer::PrepareCode() {
1944 // To make snapshots reproducible, we make a copy of the code object 1968 // To make snapshots reproducible, we make a copy of the code object
1945 // and wipe all pointers in the copy, which we then serialize. 1969 // and wipe all pointers in the copy, which we then serialize.
1946 Code* original = Code::cast(object_); 1970 Code* original = Code::cast(object_);
1947 Code* code = serializer_->CopyCode(original); 1971 Code* code = serializer_->CopyCode(original);
1948 // Code age headers are not serializable. 1972 // Code age headers are not serializable.
1949 code->MakeYoung(serializer_->isolate()); 1973 code->MakeYoung(serializer_->isolate());
1950 Address entry = original->entry();
1951 int mode_mask = RelocInfo::kCodeTargetMask | 1974 int mode_mask = RelocInfo::kCodeTargetMask |
1952 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 1975 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
1953 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 1976 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
1954 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | 1977 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
1955 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | 1978 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
1956 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); 1979 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
1957 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { 1980 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
1958 RelocInfo* rinfo = it.rinfo(); 1981 RelocInfo* rinfo = it.rinfo();
1959 RelocInfo::Mode rmode = rinfo->rmode(); 1982 if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) {
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(); 1983 rinfo->WipeOut();
1969 } 1984 }
1970 } 1985 }
1971 // We need to wipe out the header fields *after* wiping out the 1986 // We need to wipe out the header fields *after* wiping out the
1972 // relocations, because some of these fields are needed for the latter. 1987 // relocations, because some of these fields are needed for the latter.
1973 code->WipeOutHeader(); 1988 code->WipeOutHeader();
1974 return code->address(); 1989 return code->address();
1975 } 1990 }
1976 1991
1977 1992
1978 int Serializer::ObjectSerializer::OutputRawData( 1993 int Serializer::ObjectSerializer::OutputRawData(
1979 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { 1994 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) {
1980 Address object_start = object_->address(); 1995 Address object_start = object_->address();
1981 int base = bytes_processed_so_far_; 1996 int base = bytes_processed_so_far_;
1982 int up_to_offset = static_cast<int>(up_to - object_start); 1997 int up_to_offset = static_cast<int>(up_to - object_start);
1983 int to_skip = up_to_offset - bytes_processed_so_far_; 1998 int to_skip = up_to_offset - bytes_processed_so_far_;
1984 int bytes_to_output = to_skip; 1999 int bytes_to_output = to_skip;
1985 bytes_processed_so_far_ += to_skip; 2000 bytes_processed_so_far_ += to_skip;
1986 // This assert will fail if the reloc info gives us the target_address_address 2001 // This assert will fail if the reloc info gives us the target_address_address
1987 // locations in a non-ascending order. Luckily that doesn't happen. 2002 // locations in a non-ascending order. Luckily that doesn't happen.
1988 DCHECK(to_skip >= 0); 2003 DCHECK(to_skip >= 0);
Yang 2015/03/18 09:25:49 This is the assertion I was referring to.
1989 bool outputting_code = false; 2004 bool outputting_code = false;
1990 if (to_skip != 0 && code_object_ && !code_has_been_output_) { 2005 if (to_skip != 0 && code_object_ && !code_has_been_output_) {
1991 // Output the code all at once and fix later. 2006 // Output the code all at once and fix later.
1992 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; 2007 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_;
1993 outputting_code = true; 2008 outputting_code = true;
1994 code_has_been_output_ = true; 2009 code_has_been_output_ = true;
1995 } 2010 }
1996 if (bytes_to_output != 0 && 2011 if (bytes_to_output != 0 &&
1997 (!code_object_ || outputting_code)) { 2012 (!code_object_ || outputting_code)) {
1998 #define RAW_CASE(index) \ 2013 #define RAW_CASE(index) \
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 if (isolate->logger()->is_logging_code_events() || 2343 if (isolate->logger()->is_logging_code_events() ||
2329 isolate->cpu_profiler()->is_profiling()) { 2344 isolate->cpu_profiler()->is_profiling()) {
2330 String* name = isolate->heap()->empty_string(); 2345 String* name = isolate->heap()->empty_string();
2331 if (result->script()->IsScript()) { 2346 if (result->script()->IsScript()) {
2332 Script* script = Script::cast(result->script()); 2347 Script* script = Script::cast(result->script());
2333 if (script->name()->IsString()) name = String::cast(script->name()); 2348 if (script->name()->IsString()) name = String::cast(script->name());
2334 } 2349 }
2335 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(), 2350 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(),
2336 *result, NULL, name); 2351 *result, NULL, name);
2337 } 2352 }
2338
2339 return scope.CloseAndEscape(result); 2353 return scope.CloseAndEscape(result);
2340 } 2354 }
2341 2355
2342 2356
2343 void SerializedData::AllocateData(int size) { 2357 void SerializedData::AllocateData(int size) {
2344 DCHECK(!owns_data_); 2358 DCHECK(!owns_data_);
2345 data_ = NewArray<byte>(size); 2359 data_ = NewArray<byte>(size);
2346 size_ = size; 2360 size_ = size;
2347 owns_data_ = true; 2361 owns_data_ = true;
2348 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment)); 2362 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 DisallowHeapAllocation no_gc; 2574 DisallowHeapAllocation no_gc;
2561 SerializedCodeData* scd = new SerializedCodeData(cached_data); 2575 SerializedCodeData* scd = new SerializedCodeData(cached_data);
2562 SanityCheckResult r = scd->SanityCheck(isolate, source); 2576 SanityCheckResult r = scd->SanityCheck(isolate, source);
2563 if (r == CHECK_SUCCESS) return scd; 2577 if (r == CHECK_SUCCESS) return scd;
2564 cached_data->Reject(); 2578 cached_data->Reject();
2565 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); 2579 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r);
2566 delete scd; 2580 delete scd;
2567 return NULL; 2581 return NULL;
2568 } 2582 }
2569 } } // namespace v8::internal 2583 } } // 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