| 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 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1945 isolate_->InitializeLoggingAndCounters(); | 1945 isolate_->InitializeLoggingAndCounters(); |
| 1946 code_address_map_ = new CodeAddressMap(isolate_); | 1946 code_address_map_ = new CodeAddressMap(isolate_); |
| 1947 } | 1947 } |
| 1948 | 1948 |
| 1949 | 1949 |
| 1950 ScriptData* CodeSerializer::Serialize(Isolate* isolate, | 1950 ScriptData* CodeSerializer::Serialize(Isolate* isolate, |
| 1951 Handle<SharedFunctionInfo> info, | 1951 Handle<SharedFunctionInfo> info, |
| 1952 Handle<String> source) { | 1952 Handle<String> source) { |
| 1953 base::ElapsedTimer timer; | 1953 base::ElapsedTimer timer; |
| 1954 if (FLAG_profile_deserialization) timer.Start(); | 1954 if (FLAG_profile_deserialization) timer.Start(); |
| 1955 if (FLAG_serializer_trace_level > 0) { | 1955 if (FLAG_trace_code_serializer) { |
| 1956 PrintF("[Serializing from"); | 1956 PrintF("[Serializing from"); |
| 1957 Object* script = info->script(); | 1957 Object* script = info->script(); |
| 1958 if (script->IsScript()) Script::cast(script)->name()->ShortPrint(); | 1958 if (script->IsScript()) Script::cast(script)->name()->ShortPrint(); |
| 1959 PrintF("]\n"); | 1959 PrintF("]\n"); |
| 1960 } | 1960 } |
| 1961 | 1961 |
| 1962 // Serialize code object. | 1962 // Serialize code object. |
| 1963 List<byte> payload; | 1963 SnapshotByteSink sink(info->code()->CodeSize() * 2); |
| 1964 ListSnapshotSink list_sink(&payload); | 1964 CodeSerializer cs(isolate, &sink, *source, info->code()); |
| 1965 DebugSnapshotSink debug_sink(&list_sink); | |
| 1966 SnapshotByteSink* sink = FLAG_serializer_trace_level > 1 | |
| 1967 ? static_cast<SnapshotByteSink*>(&debug_sink) | |
| 1968 : static_cast<SnapshotByteSink*>(&list_sink); | |
| 1969 CodeSerializer cs(isolate, sink, *source, info->code()); | |
| 1970 DisallowHeapAllocation no_gc; | 1965 DisallowHeapAllocation no_gc; |
| 1971 Object** location = Handle<Object>::cast(info).location(); | 1966 Object** location = Handle<Object>::cast(info).location(); |
| 1972 cs.VisitPointer(location); | 1967 cs.VisitPointer(location); |
| 1973 cs.Pad(); | 1968 cs.Pad(); |
| 1974 cs.FinalizeAllocation(); | 1969 cs.FinalizeAllocation(); |
| 1975 | 1970 |
| 1976 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { | 1971 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { |
| 1977 // Fail if any chunk index exceeds the limit. | 1972 // Fail if any chunk index exceeds the limit. |
| 1978 if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) { | 1973 if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) { |
| 1979 return NULL; | 1974 return NULL; |
| 1980 } | 1975 } |
| 1981 } | 1976 } |
| 1982 | 1977 |
| 1983 SerializedCodeData data(&payload, &cs); | 1978 SerializedCodeData data(sink.data(), &cs); |
| 1984 ScriptData* script_data = data.GetScriptData(); | 1979 ScriptData* script_data = data.GetScriptData(); |
| 1985 | 1980 |
| 1986 if (FLAG_profile_deserialization) { | 1981 if (FLAG_profile_deserialization) { |
| 1987 double ms = timer.Elapsed().InMillisecondsF(); | 1982 double ms = timer.Elapsed().InMillisecondsF(); |
| 1988 int length = script_data->length(); | 1983 int length = script_data->length(); |
| 1989 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); | 1984 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); |
| 1990 } | 1985 } |
| 1991 | 1986 |
| 1992 return script_data; | 1987 return script_data; |
| 1993 } | 1988 } |
| 1994 | 1989 |
| 1995 | 1990 |
| 1996 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, | 1991 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
| 1997 WhereToPoint where_to_point, int skip) { | 1992 WhereToPoint where_to_point, int skip) { |
| 1998 int root_index = root_index_map_.Lookup(obj); | 1993 int root_index = root_index_map_.Lookup(obj); |
| 1999 if (root_index != RootIndexMap::kInvalidRootIndex) { | 1994 if (root_index != RootIndexMap::kInvalidRootIndex) { |
| 2000 if (FLAG_serializer_trace_level > 0) { | 1995 if (FLAG_trace_code_serializer) { |
| 2001 PrintF(" Encoding root: %d\n", root_index); | 1996 PrintF(" Encoding root: %d\n", root_index); |
| 2002 } | 1997 } |
| 2003 PutRoot(root_index, obj, how_to_code, where_to_point, skip); | 1998 PutRoot(root_index, obj, how_to_code, where_to_point, skip); |
| 2004 return; | 1999 return; |
| 2005 } | 2000 } |
| 2006 | 2001 |
| 2007 BackReference back_reference = back_reference_map_.Lookup(obj); | 2002 BackReference back_reference = back_reference_map_.Lookup(obj); |
| 2008 if (back_reference.is_valid()) { | 2003 if (back_reference.is_valid()) { |
| 2009 if (FLAG_serializer_trace_level > 0) { | 2004 if (FLAG_trace_code_serializer) { |
| 2010 PrintF(" Encoding back reference to: "); | 2005 PrintF(" Encoding back reference to: "); |
| 2011 obj->ShortPrint(); | 2006 obj->ShortPrint(); |
| 2012 PrintF("\n"); | 2007 PrintF("\n"); |
| 2013 } | 2008 } |
| 2014 SerializeBackReference(back_reference, how_to_code, where_to_point, skip); | 2009 SerializeBackReference(back_reference, how_to_code, where_to_point, skip); |
| 2015 return; | 2010 return; |
| 2016 } | 2011 } |
| 2017 | 2012 |
| 2018 if (skip != 0) { | 2013 if (skip != 0) { |
| 2019 sink_->Put(kSkip, "SkipFromSerializeObject"); | 2014 sink_->Put(kSkip, "SkipFromSerializeObject"); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 // There should be no hash table embedded. They would require rehashing. | 2062 // There should be no hash table embedded. They would require rehashing. |
| 2068 CHECK(!obj->IsHashTable()); | 2063 CHECK(!obj->IsHashTable()); |
| 2069 | 2064 |
| 2070 SerializeGeneric(obj, how_to_code, where_to_point); | 2065 SerializeGeneric(obj, how_to_code, where_to_point); |
| 2071 } | 2066 } |
| 2072 | 2067 |
| 2073 | 2068 |
| 2074 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, | 2069 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, |
| 2075 HowToCode how_to_code, | 2070 HowToCode how_to_code, |
| 2076 WhereToPoint where_to_point) { | 2071 WhereToPoint where_to_point) { |
| 2077 if (FLAG_serializer_trace_level > 0) { | 2072 if (FLAG_trace_code_serializer) { |
| 2078 PrintF(" Encoding heap object: "); | 2073 PrintF(" Encoding heap object: "); |
| 2079 heap_object->ShortPrint(); | 2074 heap_object->ShortPrint(); |
| 2080 PrintF("\n"); | 2075 PrintF("\n"); |
| 2081 } | 2076 } |
| 2082 | 2077 |
| 2083 if (heap_object->IsInternalizedString()) num_internalized_strings_++; | 2078 if (heap_object->IsInternalizedString()) num_internalized_strings_++; |
| 2084 | 2079 |
| 2085 // Object has not yet been serialized. Serialize it here. | 2080 // Object has not yet been serialized. Serialize it here. |
| 2086 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, | 2081 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, |
| 2087 where_to_point); | 2082 where_to_point); |
| 2088 serializer.Serialize(); | 2083 serializer.Serialize(); |
| 2089 } | 2084 } |
| 2090 | 2085 |
| 2091 | 2086 |
| 2092 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, | 2087 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, |
| 2093 WhereToPoint where_to_point) { | 2088 WhereToPoint where_to_point) { |
| 2094 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 2089 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || |
| 2095 (how_to_code == kPlain && where_to_point == kInnerPointer) || | 2090 (how_to_code == kPlain && where_to_point == kInnerPointer) || |
| 2096 (how_to_code == kFromCode && where_to_point == kInnerPointer)); | 2091 (how_to_code == kFromCode && where_to_point == kInnerPointer)); |
| 2097 DCHECK_LT(builtin_index, Builtins::builtin_count); | 2092 DCHECK_LT(builtin_index, Builtins::builtin_count); |
| 2098 DCHECK_LE(0, builtin_index); | 2093 DCHECK_LE(0, builtin_index); |
| 2099 | 2094 |
| 2100 if (FLAG_serializer_trace_level > 0) { | 2095 if (FLAG_trace_code_serializer) { |
| 2101 PrintF(" Encoding builtin: %s\n", | 2096 PrintF(" Encoding builtin: %s\n", |
| 2102 isolate()->builtins()->name(builtin_index)); | 2097 isolate()->builtins()->name(builtin_index)); |
| 2103 } | 2098 } |
| 2104 | 2099 |
| 2105 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 2100 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
| 2106 sink_->PutInt(builtin_index, "builtin_index"); | 2101 sink_->PutInt(builtin_index, "builtin_index"); |
| 2107 } | 2102 } |
| 2108 | 2103 |
| 2109 | 2104 |
| 2110 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, | 2105 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, |
| 2111 WhereToPoint where_to_point) { | 2106 WhereToPoint where_to_point) { |
| 2112 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 2107 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || |
| 2113 (how_to_code == kPlain && where_to_point == kInnerPointer) || | 2108 (how_to_code == kPlain && where_to_point == kInnerPointer) || |
| 2114 (how_to_code == kFromCode && where_to_point == kInnerPointer)); | 2109 (how_to_code == kFromCode && where_to_point == kInnerPointer)); |
| 2115 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); | 2110 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); |
| 2116 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); | 2111 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); |
| 2117 | 2112 |
| 2118 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; | 2113 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; |
| 2119 | 2114 |
| 2120 if (FLAG_serializer_trace_level > 0) { | 2115 if (FLAG_trace_code_serializer) { |
| 2121 PrintF(" Encoding code stub %s as %d\n", | 2116 PrintF(" Encoding code stub %s as %d\n", |
| 2122 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false), | 2117 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false), |
| 2123 index); | 2118 index); |
| 2124 } | 2119 } |
| 2125 | 2120 |
| 2126 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub"); | 2121 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub"); |
| 2127 sink_->PutInt(index, "CodeStub key"); | 2122 sink_->PutInt(index, "CodeStub key"); |
| 2128 } | 2123 } |
| 2129 | 2124 |
| 2130 | 2125 |
| 2131 void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code, | 2126 void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code, |
| 2132 WhereToPoint where_to_point) { | 2127 WhereToPoint where_to_point) { |
| 2133 // The IC may be implemented as a stub. | 2128 // The IC may be implemented as a stub. |
| 2134 uint32_t stub_key = ic->stub_key(); | 2129 uint32_t stub_key = ic->stub_key(); |
| 2135 if (stub_key != CodeStub::NoCacheKey()) { | 2130 if (stub_key != CodeStub::NoCacheKey()) { |
| 2136 if (FLAG_serializer_trace_level > 0) { | 2131 if (FLAG_trace_code_serializer) { |
| 2137 PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind())); | 2132 PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind())); |
| 2138 } | 2133 } |
| 2139 SerializeCodeStub(stub_key, how_to_code, where_to_point); | 2134 SerializeCodeStub(stub_key, how_to_code, where_to_point); |
| 2140 return; | 2135 return; |
| 2141 } | 2136 } |
| 2142 // The IC may be implemented as builtin. Only real builtins have an | 2137 // The IC may be implemented as builtin. Only real builtins have an |
| 2143 // actual builtin_index value attached (otherwise it's just garbage). | 2138 // actual builtin_index value attached (otherwise it's just garbage). |
| 2144 // Compare to make sure we are really dealing with a builtin. | 2139 // Compare to make sure we are really dealing with a builtin. |
| 2145 int builtin_index = ic->builtin_index(); | 2140 int builtin_index = ic->builtin_index(); |
| 2146 if (builtin_index < Builtins::builtin_count) { | 2141 if (builtin_index < Builtins::builtin_count) { |
| 2147 Builtins::Name name = static_cast<Builtins::Name>(builtin_index); | 2142 Builtins::Name name = static_cast<Builtins::Name>(builtin_index); |
| 2148 Code* builtin = isolate()->builtins()->builtin(name); | 2143 Code* builtin = isolate()->builtins()->builtin(name); |
| 2149 if (builtin == ic) { | 2144 if (builtin == ic) { |
| 2150 if (FLAG_serializer_trace_level > 0) { | 2145 if (FLAG_trace_code_serializer) { |
| 2151 PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind())); | 2146 PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind())); |
| 2152 } | 2147 } |
| 2153 DCHECK(ic->kind() == Code::KEYED_LOAD_IC || | 2148 DCHECK(ic->kind() == Code::KEYED_LOAD_IC || |
| 2154 ic->kind() == Code::KEYED_STORE_IC); | 2149 ic->kind() == Code::KEYED_STORE_IC); |
| 2155 SerializeBuiltin(builtin_index, how_to_code, where_to_point); | 2150 SerializeBuiltin(builtin_index, how_to_code, where_to_point); |
| 2156 return; | 2151 return; |
| 2157 } | 2152 } |
| 2158 } | 2153 } |
| 2159 // The IC may also just be a piece of code kept in the non_monomorphic_cache. | 2154 // The IC may also just be a piece of code kept in the non_monomorphic_cache. |
| 2160 // In that case, just serialize as a normal code object. | 2155 // In that case, just serialize as a normal code object. |
| 2161 if (FLAG_serializer_trace_level > 0) { | 2156 if (FLAG_trace_code_serializer) { |
| 2162 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind())); | 2157 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind())); |
| 2163 } | 2158 } |
| 2164 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC); | 2159 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC); |
| 2165 SerializeGeneric(ic, how_to_code, where_to_point); | 2160 SerializeGeneric(ic, how_to_code, where_to_point); |
| 2166 } | 2161 } |
| 2167 | 2162 |
| 2168 | 2163 |
| 2169 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { | 2164 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { |
| 2170 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). | 2165 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). |
| 2171 int index = 0; | 2166 int index = 0; |
| 2172 while (index < stub_keys_.length()) { | 2167 while (index < stub_keys_.length()) { |
| 2173 if (stub_keys_[index] == stub_key) return index; | 2168 if (stub_keys_[index] == stub_key) return index; |
| 2174 index++; | 2169 index++; |
| 2175 } | 2170 } |
| 2176 stub_keys_.Add(stub_key); | 2171 stub_keys_.Add(stub_key); |
| 2177 return index; | 2172 return index; |
| 2178 } | 2173 } |
| 2179 | 2174 |
| 2180 | 2175 |
| 2181 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, | 2176 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, |
| 2182 WhereToPoint where_to_point) { | 2177 WhereToPoint where_to_point) { |
| 2183 if (FLAG_serializer_trace_level > 0) PrintF(" Encoding source object\n"); | 2178 if (FLAG_trace_code_serializer) PrintF(" Encoding source object\n"); |
| 2184 | 2179 |
| 2185 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); | 2180 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); |
| 2186 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); | 2181 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); |
| 2187 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); | 2182 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); |
| 2188 } | 2183 } |
| 2189 | 2184 |
| 2190 | 2185 |
| 2191 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( | 2186 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
| 2192 Isolate* isolate, ScriptData* data, Handle<String> source) { | 2187 Isolate* isolate, ScriptData* data, Handle<String> source) { |
| 2193 base::ElapsedTimer timer; | 2188 base::ElapsedTimer timer; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 double ms = timer.Elapsed().InMillisecondsF(); | 2236 double ms = timer.Elapsed().InMillisecondsF(); |
| 2242 int length = data->length(); | 2237 int length = data->length(); |
| 2243 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); | 2238 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); |
| 2244 } | 2239 } |
| 2245 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate); | 2240 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate); |
| 2246 result->set_deserialized(true); | 2241 result->set_deserialized(true); |
| 2247 return result; | 2242 return result; |
| 2248 } | 2243 } |
| 2249 | 2244 |
| 2250 | 2245 |
| 2251 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) | 2246 SerializedCodeData::SerializedCodeData(const List<byte>& payload, |
| 2247 CodeSerializer* cs) |
| 2252 : script_data_(NULL), owns_script_data_(true) { | 2248 : script_data_(NULL), owns_script_data_(true) { |
| 2253 DisallowHeapAllocation no_gc; | 2249 DisallowHeapAllocation no_gc; |
| 2254 List<uint32_t>* stub_keys = cs->stub_keys(); | 2250 List<uint32_t>* stub_keys = cs->stub_keys(); |
| 2255 | 2251 |
| 2256 // Gather reservation chunk sizes. | 2252 // Gather reservation chunk sizes. |
| 2257 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); | 2253 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); |
| 2258 STATIC_ASSERT(NEW_SPACE == 0); | 2254 STATIC_ASSERT(NEW_SPACE == 0); |
| 2259 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { | 2255 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { |
| 2260 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); | 2256 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); |
| 2261 for (int j = 0; j < chunks.length(); j++) { | 2257 for (int j = 0; j < chunks.length(); j++) { |
| 2262 DCHECK(i == LO_SPACE || | 2258 DCHECK(i == LO_SPACE || |
| 2263 chunks[j] <= | 2259 chunks[j] <= |
| 2264 static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)); | 2260 static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)); |
| 2265 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) | | 2261 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) | |
| 2266 IsLastChunkBits::encode(j == chunks.length() - 1); | 2262 IsLastChunkBits::encode(j == chunks.length() - 1); |
| 2267 reservations.Add(chunk); | 2263 reservations.Add(chunk); |
| 2268 } | 2264 } |
| 2269 } | 2265 } |
| 2270 | 2266 |
| 2271 // Calculate sizes. | 2267 // Calculate sizes. |
| 2272 int reservation_size = reservations.length() * kInt32Size; | 2268 int reservation_size = reservations.length() * kInt32Size; |
| 2273 int num_stub_keys = stub_keys->length(); | 2269 int num_stub_keys = stub_keys->length(); |
| 2274 int stub_keys_size = stub_keys->length() * kInt32Size; | 2270 int stub_keys_size = stub_keys->length() * kInt32Size; |
| 2275 int data_length = | 2271 int data_length = |
| 2276 kHeaderSize + reservation_size + stub_keys_size + payload->length(); | 2272 kHeaderSize + reservation_size + stub_keys_size + payload.length(); |
| 2277 | 2273 |
| 2278 // Allocate backing store and create result data. | 2274 // Allocate backing store and create result data. |
| 2279 byte* data = NewArray<byte>(data_length); | 2275 byte* data = NewArray<byte>(data_length); |
| 2280 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2276 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
| 2281 script_data_ = new ScriptData(data, data_length); | 2277 script_data_ = new ScriptData(data, data_length); |
| 2282 script_data_->AcquireDataOwnership(); | 2278 script_data_->AcquireDataOwnership(); |
| 2283 | 2279 |
| 2284 // Set header values. | 2280 // Set header values. |
| 2285 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); | 2281 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
| 2286 SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings()); | 2282 SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings()); |
| 2287 SetHeaderValue(kReservationsOffset, reservations.length()); | 2283 SetHeaderValue(kReservationsOffset, reservations.length()); |
| 2288 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2284 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
| 2289 SetHeaderValue(kPayloadLengthOffset, payload->length()); | 2285 SetHeaderValue(kPayloadLengthOffset, payload.length()); |
| 2290 | 2286 |
| 2291 // Copy reservation chunk sizes. | 2287 // Copy reservation chunk sizes. |
| 2292 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), | 2288 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), |
| 2293 reservation_size); | 2289 reservation_size); |
| 2294 | 2290 |
| 2295 // Copy code stub keys. | 2291 // Copy code stub keys. |
| 2296 CopyBytes(data + kHeaderSize + reservation_size, | 2292 CopyBytes(data + kHeaderSize + reservation_size, |
| 2297 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); | 2293 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); |
| 2298 | 2294 |
| 2299 // Copy serialized data. | 2295 // Copy serialized data. |
| 2300 CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size, | 2296 CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size, |
| 2301 payload->begin(), static_cast<size_t>(payload->length())); | 2297 payload.begin(), static_cast<size_t>(payload.length())); |
| 2302 } | 2298 } |
| 2303 | 2299 |
| 2304 | 2300 |
| 2305 bool SerializedCodeData::IsSane(String* source) { | 2301 bool SerializedCodeData::IsSane(String* source) { |
| 2306 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && | 2302 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && |
| 2307 PayloadLength() >= SharedFunctionInfo::kSize; | 2303 PayloadLength() >= SharedFunctionInfo::kSize; |
| 2308 } | 2304 } |
| 2309 | 2305 |
| 2310 | 2306 |
| 2311 int SerializedCodeData::CheckSum(String* string) { | 2307 int SerializedCodeData::CheckSum(String* string) { |
| 2312 int checksum = Version::Hash(); | 2308 int checksum = Version::Hash(); |
| 2313 #ifdef DEBUG | 2309 #ifdef DEBUG |
| 2314 uint32_t seed = static_cast<uint32_t>(checksum); | 2310 uint32_t seed = static_cast<uint32_t>(checksum); |
| 2315 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2311 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
| 2316 #endif // DEBUG | 2312 #endif // DEBUG |
| 2317 return checksum; | 2313 return checksum; |
| 2318 } | 2314 } |
| 2319 } } // namespace v8::internal | 2315 } } // namespace v8::internal |
| OLD | NEW |