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

Side by Side Diff: src/serialize.cc

Issue 556243005: Serialize code stubs using stub key. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/serialize.h ('k') | no next file » | 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"
11 #include "src/code-stubs.h"
11 #include "src/deoptimizer.h" 12 #include "src/deoptimizer.h"
12 #include "src/execution.h" 13 #include "src/execution.h"
13 #include "src/global-handles.h" 14 #include "src/global-handles.h"
14 #include "src/ic/ic.h" 15 #include "src/ic/ic.h"
15 #include "src/ic/stub-cache.h" 16 #include "src/ic/stub-cache.h"
16 #include "src/natives.h" 17 #include "src/natives.h"
17 #include "src/objects.h" 18 #include "src/objects.h"
18 #include "src/runtime.h" 19 #include "src/runtime.h"
19 #include "src/serialize.h" 20 #include "src/serialize.h"
20 #include "src/snapshot.h" 21 #include "src/snapshot.h"
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 DCHECK(deserializing_user_code()); \ 866 DCHECK(deserializing_user_code()); \
866 int builtin_id = source_->GetInt(); \ 867 int builtin_id = source_->GetInt(); \
867 DCHECK_LE(0, builtin_id); \ 868 DCHECK_LE(0, builtin_id); \
868 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 869 DCHECK_LT(builtin_id, Builtins::builtin_count); \
869 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 870 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
870 new_object = isolate->builtins()->builtin(name); \ 871 new_object = isolate->builtins()->builtin(name); \
871 emit_write_barrier = false; \ 872 emit_write_barrier = false; \
872 } else if (where == kAttachedReference) { \ 873 } else if (where == kAttachedReference) { \
873 DCHECK(deserializing_user_code()); \ 874 DCHECK(deserializing_user_code()); \
874 int index = source_->GetInt(); \ 875 int index = source_->GetInt(); \
875 new_object = attached_objects_->at(index); \ 876 new_object = *attached_objects_->at(index); \
876 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 877 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
877 } else { \ 878 } else { \
878 DCHECK(where == kBackrefWithSkip); \ 879 DCHECK(where == kBackrefWithSkip); \
879 int skip = source_->GetInt(); \ 880 int skip = source_->GetInt(); \
880 current = reinterpret_cast<Object**>( \ 881 current = reinterpret_cast<Object**>( \
881 reinterpret_cast<Address>(current) + skip); \ 882 reinterpret_cast<Address>(current) + skip); \
882 emit_write_barrier = (space_number == NEW_SPACE); \ 883 emit_write_barrier = (space_number == NEW_SPACE); \
883 new_object = GetAddressFromEnd(data & kSpaceMask); \ 884 new_object = GetAddressFromEnd(data & kSpaceMask); \
884 if (deserializing_user_code()) { \ 885 if (deserializing_user_code()) { \
885 new_object = ProcessBackRefInSerializedCode(new_object); \ 886 new_object = ProcessBackRefInSerializedCode(new_object); \
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0) 1131 CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0)
1131 CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0) 1132 CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0)
1132 #endif 1133 #endif
1133 // Find a builtin and write a pointer to it in the current code object. 1134 // Find a builtin and write a pointer to it in the current code object.
1134 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) 1135 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
1135 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) 1136 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
1136 // Find an object in the attached references and write a pointer to it to 1137 // Find an object in the attached references and write a pointer to it to
1137 // the current object. 1138 // the current object.
1138 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) 1139 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0)
1139 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) 1140 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0)
1141 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0)
1142 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0)
1143 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0)
1144 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0)
1140 1145
1141 #undef CASE_STATEMENT 1146 #undef CASE_STATEMENT
1142 #undef CASE_BODY 1147 #undef CASE_BODY
1143 #undef ALL_SPACES 1148 #undef ALL_SPACES
1144 1149
1145 case kSkip: { 1150 case kSkip: {
1146 int size = source_->GetInt(); 1151 int size = source_->GetInt();
1147 current = reinterpret_cast<Object**>( 1152 current = reinterpret_cast<Object**>(
1148 reinterpret_cast<intptr_t>(current) + size); 1153 reinterpret_cast<intptr_t>(current) + size);
1149 break; 1154 break;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 } 1312 }
1308 } 1313 }
1309 return kInvalidRootIndex; 1314 return kInvalidRootIndex;
1310 } 1315 }
1311 1316
1312 1317
1313 // Encode the location of an already deserialized object in order to write its 1318 // Encode the location of an already deserialized object in order to write its
1314 // location into a later object. We can encode the location as an offset from 1319 // location into a later object. We can encode the location as an offset from
1315 // the start of the deserialized objects or as an offset backwards from the 1320 // the start of the deserialized objects or as an offset backwards from the
1316 // current allocation pointer. 1321 // current allocation pointer.
1317 void Serializer::SerializeReferenceToPreviousObject( 1322 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object,
1318 int space, 1323 HowToCode how_to_code,
1319 int address, 1324 WhereToPoint where_to_point,
1320 HowToCode how_to_code, 1325 int skip) {
1321 WhereToPoint where_to_point, 1326 int space = SpaceOfObject(heap_object);
1322 int skip) { 1327 int address = address_mapper_.MappedTo(heap_object);
1323 int offset = CurrentAllocationAddress(space) - address; 1328 int offset = CurrentAllocationAddress(space) - address;
1324 // Shift out the bits that are always 0. 1329 // Shift out the bits that are always 0.
1325 offset >>= kObjectAlignmentBits; 1330 offset >>= kObjectAlignmentBits;
1326 if (skip == 0) { 1331 if (skip == 0) {
1327 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); 1332 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
1328 } else { 1333 } else {
1329 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, 1334 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
1330 "BackRefSerWithSkip"); 1335 "BackRefSerWithSkip");
1331 sink_->PutInt(skip, "BackRefSkipDistance"); 1336 sink_->PutInt(skip, "BackRefSkipDistance");
1332 } 1337 }
(...skipping 10 matching lines...) Expand all
1343 HeapObject* heap_object = HeapObject::cast(o); 1348 HeapObject* heap_object = HeapObject::cast(o);
1344 DCHECK(!heap_object->IsJSFunction()); 1349 DCHECK(!heap_object->IsJSFunction());
1345 1350
1346 int root_index; 1351 int root_index;
1347 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { 1352 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
1348 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); 1353 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
1349 return; 1354 return;
1350 } 1355 }
1351 1356
1352 if (address_mapper_.IsMapped(heap_object)) { 1357 if (address_mapper_.IsMapped(heap_object)) {
1353 int space = SpaceOfObject(heap_object); 1358 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
1354 int address = address_mapper_.MappedTo(heap_object);
1355 SerializeReferenceToPreviousObject(space,
1356 address,
1357 how_to_code,
1358 where_to_point,
1359 skip); 1359 skip);
1360 } else { 1360 } else {
1361 if (skip != 0) { 1361 if (skip != 0) {
1362 sink_->Put(kSkip, "FlushPendingSkip"); 1362 sink_->Put(kSkip, "FlushPendingSkip");
1363 sink_->PutInt(skip, "SkipDistance"); 1363 sink_->PutInt(skip, "SkipDistance");
1364 } 1364 }
1365 1365
1366 // Object has not yet been serialized. Serialize it here. 1366 // Object has not yet been serialized. Serialize it here.
1367 ObjectSerializer object_serializer(this, 1367 ObjectSerializer object_serializer(this,
1368 heap_object, 1368 heap_object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 1451
1452 // Pointers from the partial snapshot to the objects in the startup snapshot 1452 // Pointers from the partial snapshot to the objects in the startup snapshot
1453 // should go through the root array or through the partial snapshot cache. 1453 // should go through the root array or through the partial snapshot cache.
1454 // If this is not the case you may have to add something to the root array. 1454 // If this is not the case you may have to add something to the root array.
1455 DCHECK(!startup_serializer_->address_mapper()->IsMapped(heap_object)); 1455 DCHECK(!startup_serializer_->address_mapper()->IsMapped(heap_object));
1456 // All the internalized strings that the partial snapshot needs should be 1456 // All the internalized strings that the partial snapshot needs should be
1457 // either in the root table or in the partial snapshot cache. 1457 // either in the root table or in the partial snapshot cache.
1458 DCHECK(!heap_object->IsInternalizedString()); 1458 DCHECK(!heap_object->IsInternalizedString());
1459 1459
1460 if (address_mapper_.IsMapped(heap_object)) { 1460 if (address_mapper_.IsMapped(heap_object)) {
1461 int space = SpaceOfObject(heap_object); 1461 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
1462 int address = address_mapper_.MappedTo(heap_object);
1463 SerializeReferenceToPreviousObject(space,
1464 address,
1465 how_to_code,
1466 where_to_point,
1467 skip); 1462 skip);
1468 } else { 1463 } else {
1469 if (skip != 0) { 1464 if (skip != 0) {
1470 sink_->Put(kSkip, "SkipFromSerializeObject"); 1465 sink_->Put(kSkip, "SkipFromSerializeObject");
1471 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); 1466 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
1472 } 1467 }
1473 // Object has not yet been serialized. Serialize it here. 1468 // Object has not yet been serialized. Serialize it here.
1474 ObjectSerializer serializer(this, 1469 ObjectSerializer serializer(this,
1475 heap_object, 1470 heap_object,
1476 sink_, 1471 sink_,
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 1775
1781 void Serializer::InitializeCodeAddressMap() { 1776 void Serializer::InitializeCodeAddressMap() {
1782 isolate_->InitializeLoggingAndCounters(); 1777 isolate_->InitializeLoggingAndCounters();
1783 code_address_map_ = new CodeAddressMap(isolate_); 1778 code_address_map_ = new CodeAddressMap(isolate_);
1784 } 1779 }
1785 1780
1786 1781
1787 ScriptData* CodeSerializer::Serialize(Isolate* isolate, 1782 ScriptData* CodeSerializer::Serialize(Isolate* isolate,
1788 Handle<SharedFunctionInfo> info, 1783 Handle<SharedFunctionInfo> info,
1789 Handle<String> source) { 1784 Handle<String> source) {
1785 base::ElapsedTimer timer;
1786 if (FLAG_profile_deserialization) timer.Start();
1787
1790 // Serialize code object. 1788 // Serialize code object.
1791 List<byte> payload; 1789 List<byte> payload;
1792 ListSnapshotSink list_sink(&payload); 1790 ListSnapshotSink list_sink(&payload);
1793 CodeSerializer cs(isolate, &list_sink, *source); 1791 DebugSnapshotSink debug_sink(&list_sink);
1792 SnapshotByteSink* sink = FLAG_trace_code_serializer
1793 ? static_cast<SnapshotByteSink*>(&debug_sink)
1794 : static_cast<SnapshotByteSink*>(&list_sink);
1795 CodeSerializer cs(isolate, sink, *source);
1794 DisallowHeapAllocation no_gc; 1796 DisallowHeapAllocation no_gc;
1795 Object** location = Handle<Object>::cast(info).location(); 1797 Object** location = Handle<Object>::cast(info).location();
1796 cs.VisitPointer(location); 1798 cs.VisitPointer(location);
1797 cs.Pad(); 1799 cs.Pad();
1798 1800
1799 SerializedCodeData data(&payload, &cs); 1801 SerializedCodeData data(&payload, &cs);
1800 return data.GetScriptData(); 1802 ScriptData* script_data = data.GetScriptData();
1803
1804 if (FLAG_profile_deserialization) {
1805 double ms = timer.Elapsed().InMillisecondsF();
1806 int length = script_data->length();
1807 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms);
1808 }
1809
1810 return script_data;
1801 } 1811 }
1802 1812
1803 1813
1804 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, 1814 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
1805 WhereToPoint where_to_point, int skip) { 1815 WhereToPoint where_to_point, int skip) {
1806 CHECK(o->IsHeapObject()); 1816 CHECK(o->IsHeapObject());
1807 HeapObject* heap_object = HeapObject::cast(o); 1817 HeapObject* heap_object = HeapObject::cast(o);
1808 1818
1809 // The code-caches link to context-specific code objects, which 1819 // The code-caches link to context-specific code objects, which
1810 // the startup and context serializes cannot currently handle. 1820 // the startup and context serializes cannot currently handle.
1811 DCHECK(!heap_object->IsMap() || 1821 DCHECK(!heap_object->IsMap() ||
1812 Map::cast(heap_object)->code_cache() == 1822 Map::cast(heap_object)->code_cache() ==
1813 heap_object->GetHeap()->empty_fixed_array()); 1823 heap_object->GetHeap()->empty_fixed_array());
1814 1824
1815 int root_index; 1825 int root_index;
1816 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { 1826 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
1817 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); 1827 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
1818 return; 1828 return;
1819 } 1829 }
1820 1830
1821 // TODO(yangguo) wire up stubs from stub cache.
1822 // TODO(yangguo) wire up global object. 1831 // TODO(yangguo) wire up global object.
1823 // TODO(yangguo) We cannot deal with different hash seeds yet. 1832 // TODO(yangguo) We cannot deal with different hash seeds yet.
1824 DCHECK(!heap_object->IsHashTable()); 1833 DCHECK(!heap_object->IsHashTable());
1825 1834
1826 if (address_mapper_.IsMapped(heap_object)) { 1835 if (address_mapper_.IsMapped(heap_object)) {
1827 int space = SpaceOfObject(heap_object); 1836 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
1828 int address = address_mapper_.MappedTo(heap_object); 1837 skip);
1829 SerializeReferenceToPreviousObject(space, address, how_to_code,
1830 where_to_point, skip);
1831 return; 1838 return;
1832 } 1839 }
1833 1840
1834 if (heap_object->IsCode()) { 1841 if (heap_object->IsCode()) {
1835 Code* code_object = Code::cast(heap_object); 1842 Code* code_object = Code::cast(heap_object);
1836 if (code_object->kind() == Code::BUILTIN) { 1843 if (code_object->kind() == Code::BUILTIN) {
1837 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); 1844 SerializeBuiltin(code_object, how_to_code, where_to_point, skip);
1838 return; 1845 return;
1839 } 1846 }
1840 // TODO(yangguo) figure out whether other code kinds can be handled smarter. 1847 if (code_object->IsCodeStubOrIC()) {
1848 SerializeCodeStub(code_object, how_to_code, where_to_point, skip);
1849 return;
1850 }
1851 code_object->ClearInlineCaches();
1841 } 1852 }
1842 1853
1843 if (heap_object == source_) { 1854 if (heap_object == source_) {
1844 SerializeSourceObject(how_to_code, where_to_point, skip); 1855 SerializeSourceObject(how_to_code, where_to_point, skip);
1845 return; 1856 return;
1846 } 1857 }
1847 1858
1859 SerializeHeapObject(heap_object, how_to_code, where_to_point, skip);
1860 }
1861
1862
1863 void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
1864 HowToCode how_to_code,
1865 WhereToPoint where_to_point,
1866 int skip) {
1848 if (heap_object->IsScript()) { 1867 if (heap_object->IsScript()) {
1849 // The wrapper cache uses a Foreign object to point to a global handle. 1868 // The wrapper cache uses a Foreign object to point to a global handle.
1850 // However, the object visitor expects foreign objects to point to external 1869 // However, the object visitor expects foreign objects to point to external
1851 // references. Clear the cache to avoid this issue. 1870 // references. Clear the cache to avoid this issue.
1852 Script::cast(heap_object)->ClearWrapperCache(); 1871 Script::cast(heap_object)->ClearWrapperCache();
1853 } 1872 }
1854 1873
1855 if (skip != 0) { 1874 if (skip != 0) {
1856 sink_->Put(kSkip, "SkipFromSerializeObject"); 1875 sink_->Put(kSkip, "SkipFromSerializeObject");
1857 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); 1876 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
1858 } 1877 }
1878
1879 if (FLAG_trace_code_serializer) {
1880 PrintF("Encoding heap object: ");
1881 heap_object->ShortPrint();
1882 PrintF("\n");
1883 }
1884
1859 // Object has not yet been serialized. Serialize it here. 1885 // Object has not yet been serialized. Serialize it here.
1860 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, 1886 ObjectSerializer serializer(this, heap_object, sink_, how_to_code,
1861 where_to_point); 1887 where_to_point);
1862 serializer.Serialize(); 1888 serializer.Serialize();
1863 } 1889 }
1864 1890
1865 1891
1866 void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code, 1892 void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
1867 WhereToPoint where_to_point, int skip) { 1893 WhereToPoint where_to_point, int skip) {
1868 if (skip != 0) { 1894 if (skip != 0) {
1869 sink_->Put(kSkip, "SkipFromSerializeBuiltin"); 1895 sink_->Put(kSkip, "SkipFromSerializeBuiltin");
1870 sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin"); 1896 sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
1871 } 1897 }
1872 1898
1873 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || 1899 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
1874 (how_to_code == kPlain && where_to_point == kInnerPointer) || 1900 (how_to_code == kPlain && where_to_point == kInnerPointer) ||
1875 (how_to_code == kFromCode && where_to_point == kInnerPointer)); 1901 (how_to_code == kFromCode && where_to_point == kInnerPointer));
1876 int builtin_index = builtin->builtin_index(); 1902 int builtin_index = builtin->builtin_index();
1877 DCHECK_LT(builtin_index, Builtins::builtin_count); 1903 DCHECK_LT(builtin_index, Builtins::builtin_count);
1878 DCHECK_LE(0, builtin_index); 1904 DCHECK_LE(0, builtin_index);
1905
1906 if (FLAG_trace_code_serializer) {
1907 PrintF("Encoding builtin: %s\n",
1908 isolate()->builtins()->name(builtin_index));
1909 }
1910
1879 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); 1911 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin");
1880 sink_->PutInt(builtin_index, "builtin_index"); 1912 sink_->PutInt(builtin_index, "builtin_index");
1881 } 1913 }
1882 1914
1883 1915
1916 void CodeSerializer::SerializeCodeStub(Code* code, HowToCode how_to_code,
1917 WhereToPoint where_to_point, int skip) {
1918 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
1919 (how_to_code == kPlain && where_to_point == kInnerPointer) ||
1920 (how_to_code == kFromCode && where_to_point == kInnerPointer));
1921 uint32_t stub_key = code->stub_key();
1922
1923 if (CodeStub::MajorKeyFromKey(stub_key) == CodeStub::NoCacheKey()) {
1924 if (FLAG_trace_code_serializer) {
1925 PrintF("Encoding uncacheable code stub as heap object\n");
1926 }
1927 SerializeHeapObject(code, how_to_code, where_to_point, skip);
1928 return;
1929 }
1930
1931 if (skip != 0) {
1932 sink_->Put(kSkip, "SkipFromSerializeCodeStub");
1933 sink_->PutInt(skip, "SkipDistanceFromSerializeCodeStub");
1934 }
1935
1936 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
1937
1938 if (FLAG_trace_code_serializer) {
1939 PrintF("Encoding code stub %s as %d\n",
1940 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false),
1941 index);
1942 }
1943
1944 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub");
1945 sink_->PutInt(index, "CodeStub key");
1946 }
1947
1948
1949 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
1950 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2).
1951 int index = 0;
1952 while (index < stub_keys_.length()) {
1953 if (stub_keys_[index] == stub_key) return index;
1954 index++;
1955 }
1956 stub_keys_.Add(stub_key);
1957 return index;
1958 }
1959
1960
1884 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, 1961 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
1885 WhereToPoint where_to_point, 1962 WhereToPoint where_to_point,
1886 int skip) { 1963 int skip) {
1887 if (skip != 0) { 1964 if (skip != 0) {
1888 sink_->Put(kSkip, "SkipFromSerializeSourceObject"); 1965 sink_->Put(kSkip, "SkipFromSerializeSourceObject");
1889 sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject"); 1966 sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
1890 } 1967 }
1891 1968
1969 if (FLAG_trace_code_serializer) {
1970 PrintF("Encoding source object\n");
1971 }
1972
1892 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); 1973 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
1893 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); 1974 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
1894 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); 1975 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
1895 } 1976 }
1896 1977
1897 1978
1898 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate, 1979 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
1899 ScriptData* data, 1980 ScriptData* data,
1900 Handle<String> source) { 1981 Handle<String> source) {
1901 base::ElapsedTimer timer; 1982 base::ElapsedTimer timer;
1902 if (FLAG_profile_deserialization) timer.Start(); 1983 if (FLAG_profile_deserialization) timer.Start();
1903 SerializedCodeData scd(data, *source); 1984
1904 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); 1985 Object* root;
1905 Deserializer deserializer(&payload); 1986
1906 STATIC_ASSERT(NEW_SPACE == 0); 1987 {
1907 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { 1988 HandleScope scope(isolate);
1908 deserializer.set_reservation(i, scd.GetReservation(i)); 1989
1990 SerializedCodeData scd(data, *source);
1991 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
1992 Deserializer deserializer(&payload);
1993 STATIC_ASSERT(NEW_SPACE == 0);
1994 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
1995 deserializer.set_reservation(i, scd.GetReservation(i));
1996 }
1997
1998 // Prepare and register list of attached objects.
1999 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
2000 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
2001 code_stub_keys.length() + kCodeStubsBaseIndex);
2002 attached_objects[kSourceObjectIndex] = source;
2003 for (int i = 0; i < code_stub_keys.length(); i++) {
2004 attached_objects[i + kCodeStubsBaseIndex] =
2005 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
2006 }
2007 deserializer.SetAttachedObjects(&attached_objects);
2008
2009 // Deserialize.
2010 deserializer.DeserializePartial(isolate, &root);
2011 deserializer.FlushICacheForNewCodeObjects();
1909 } 2012 }
1910 2013
1911 // Prepare and register list of attached objects.
1912 Vector<Object*> attached_objects = Vector<Object*>::New(1);
1913 attached_objects[kSourceObjectIndex] = *source;
1914 deserializer.SetAttachedObjects(&attached_objects);
1915
1916 Object* root;
1917 deserializer.DeserializePartial(isolate, &root);
1918 deserializer.FlushICacheForNewCodeObjects();
1919 if (FLAG_profile_deserialization) { 2014 if (FLAG_profile_deserialization) {
1920 double ms = timer.Elapsed().InMillisecondsF(); 2015 double ms = timer.Elapsed().InMillisecondsF();
1921 int length = data->length(); 2016 int length = data->length();
1922 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); 2017 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms);
1923 } 2018 }
1924 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate); 2019 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate);
1925 } 2020 }
1926 2021
1927 2022
1928 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) 2023 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
1929 : owns_script_data_(true) { 2024 : owns_script_data_(true) {
1930 DisallowHeapAllocation no_gc; 2025 DisallowHeapAllocation no_gc;
1931 int data_length = payload->length() + kHeaderEntries * kIntSize; 2026 List<uint32_t>* stub_keys = cs->stub_keys();
2027
2028 // Calculate sizes.
2029 int num_stub_keys = stub_keys->length();
2030 int stub_keys_size = stub_keys->length() * kInt32Size;
2031 int data_length = kHeaderSize + stub_keys_size + payload->length();
2032
2033 // Allocate backing store and create result data.
1932 byte* data = NewArray<byte>(data_length); 2034 byte* data = NewArray<byte>(data_length);
1933 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); 2035 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
1934 CopyBytes(data + kHeaderEntries * kIntSize, payload->begin(),
1935 static_cast<size_t>(payload->length()));
1936 script_data_ = new ScriptData(data, data_length); 2036 script_data_ = new ScriptData(data, data_length);
1937 script_data_->AcquireDataOwnership(); 2037 script_data_->AcquireDataOwnership();
2038
2039 // Set header values.
1938 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); 2040 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
2041 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
2042 SetHeaderValue(kPayloadLengthOffset, payload->length());
1939 STATIC_ASSERT(NEW_SPACE == 0); 2043 STATIC_ASSERT(NEW_SPACE == 0);
1940 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { 2044 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
1941 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); 2045 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i));
1942 } 2046 }
2047
2048 // Copy code stub keys.
2049 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()),
2050 stub_keys_size);
2051
2052 // Copy serialized data.
2053 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(),
2054 static_cast<size_t>(payload->length()));
1943 } 2055 }
1944 2056
1945 2057
1946 bool SerializedCodeData::IsSane(String* source) { 2058 bool SerializedCodeData::IsSane(String* source) {
1947 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && 2059 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
1948 PayloadLength() >= SharedFunctionInfo::kSize; 2060 PayloadLength() >= SharedFunctionInfo::kSize;
1949 } 2061 }
1950 2062
1951 2063
1952 int SerializedCodeData::CheckSum(String* string) { 2064 int SerializedCodeData::CheckSum(String* string) {
1953 int checksum = Version::Hash(); 2065 int checksum = Version::Hash();
1954 #ifdef DEBUG 2066 #ifdef DEBUG
1955 uint32_t seed = static_cast<uint32_t>(checksum); 2067 uint32_t seed = static_cast<uint32_t>(checksum);
1956 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); 2068 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed));
1957 #endif // DEBUG 2069 #endif // DEBUG
1958 return checksum; 2070 return checksum;
1959 } 2071 }
1960 } } // namespace v8::internal 2072 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698