| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/snapshot/code-serializer.h" | 5 #include "src/snapshot/code-serializer.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/log.h" | 8 #include "src/log.h" |
| 9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
| 10 #include "src/profiler/cpu-profiler.h" | 10 #include "src/profiler/cpu-profiler.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 case Code::BYTECODE_HANDLER: // No direct references to handlers. | 69 case Code::BYTECODE_HANDLER: // No direct references to handlers. |
| 70 CHECK(false); | 70 CHECK(false); |
| 71 case Code::BUILTIN: | 71 case Code::BUILTIN: |
| 72 SerializeBuiltin(code_object->builtin_index(), how_to_code, | 72 SerializeBuiltin(code_object->builtin_index(), how_to_code, |
| 73 where_to_point); | 73 where_to_point); |
| 74 return; | 74 return; |
| 75 case Code::STUB: | 75 case Code::STUB: |
| 76 #define IC_KIND_CASE(KIND) case Code::KIND: | 76 #define IC_KIND_CASE(KIND) case Code::KIND: |
| 77 IC_KIND_LIST(IC_KIND_CASE) | 77 IC_KIND_LIST(IC_KIND_CASE) |
| 78 #undef IC_KIND_CASE | 78 #undef IC_KIND_CASE |
| 79 SerializeCodeStub(code_object->stub_key(), how_to_code, where_to_point); | 79 SerializeCodeStub(code_object, how_to_code, where_to_point); |
| 80 return; | 80 return; |
| 81 case Code::FUNCTION: | 81 case Code::FUNCTION: |
| 82 DCHECK(code_object->has_reloc_info_for_serialization()); | 82 DCHECK(code_object->has_reloc_info_for_serialization()); |
| 83 SerializeGeneric(code_object, how_to_code, where_to_point); | 83 SerializeGeneric(code_object, how_to_code, where_to_point); |
| 84 return; | 84 return; |
| 85 case Code::WASM_FUNCTION: | 85 case Code::WASM_FUNCTION: |
| 86 case Code::WASM_TO_JS_FUNCTION: | 86 case Code::WASM_TO_JS_FUNCTION: |
| 87 case Code::JS_TO_WASM_FUNCTION: | 87 case Code::JS_TO_WASM_FUNCTION: |
| 88 UNREACHABLE(); | 88 UNREACHABLE(); |
| 89 } | 89 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 | 121 |
| 122 if (FLAG_trace_serializer) { | 122 if (FLAG_trace_serializer) { |
| 123 PrintF(" Encoding builtin: %s\n", | 123 PrintF(" Encoding builtin: %s\n", |
| 124 isolate()->builtins()->name(builtin_index)); | 124 isolate()->builtins()->name(builtin_index)); |
| 125 } | 125 } |
| 126 | 126 |
| 127 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 127 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
| 128 sink_->PutInt(builtin_index, "builtin_index"); | 128 sink_->PutInt(builtin_index, "builtin_index"); |
| 129 } | 129 } |
| 130 | 130 |
| 131 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, | 131 void CodeSerializer::SerializeCodeStub(Code* code_stub, HowToCode how_to_code, |
| 132 WhereToPoint where_to_point) { | 132 WhereToPoint where_to_point) { |
| 133 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 133 // We only arrive here if we have not encountered this code stub before. |
| 134 (how_to_code == kPlain && where_to_point == kInnerPointer) || | 134 DCHECK(!reference_map()->Lookup(code_stub).is_valid()); |
| 135 (how_to_code == kFromCode && where_to_point == kInnerPointer)); | 135 uint32_t stub_key = code_stub->stub_key(); |
| 136 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); | 136 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); |
| 137 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); | 137 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); |
| 138 stub_keys_.Add(stub_key); |
| 138 | 139 |
| 139 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; | 140 SerializerReference reference = |
| 140 | 141 reference_map()->AddAttachedReference(code_stub); |
| 141 if (FLAG_trace_serializer) { | 142 if (FLAG_trace_serializer) { |
| 142 PrintF(" Encoding code stub %s as %d\n", | 143 PrintF(" Encoding code stub %s as attached reference %d\n", |
| 143 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key)), index); | 144 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key)), |
| 145 reference.attached_reference_index()); |
| 144 } | 146 } |
| 145 | 147 PutAttachedReference(reference, how_to_code, where_to_point); |
| 146 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub"); | |
| 147 sink_->PutInt(index, "CodeStub key"); | |
| 148 } | |
| 149 | |
| 150 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { | |
| 151 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). | |
| 152 int index = 0; | |
| 153 while (index < stub_keys_.length()) { | |
| 154 if (stub_keys_[index] == stub_key) return index; | |
| 155 index++; | |
| 156 } | |
| 157 stub_keys_.Add(stub_key); | |
| 158 return index; | |
| 159 } | 148 } |
| 160 | 149 |
| 161 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( | 150 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
| 162 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { | 151 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { |
| 163 base::ElapsedTimer timer; | 152 base::ElapsedTimer timer; |
| 164 if (FLAG_profile_deserialization) timer.Start(); | 153 if (FLAG_profile_deserialization) timer.Start(); |
| 165 | 154 |
| 166 HandleScope scope(isolate); | 155 HandleScope scope(isolate); |
| 167 | 156 |
| 168 base::SmartPointer<SerializedCodeData> scd( | 157 base::SmartPointer<SerializedCodeData> scd( |
| 169 SerializedCodeData::FromCachedData(isolate, cached_data, *source)); | 158 SerializedCodeData::FromCachedData(isolate, cached_data, *source)); |
| 170 if (scd.is_empty()) { | 159 if (scd.is_empty()) { |
| 171 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); | 160 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); |
| 172 DCHECK(cached_data->rejected()); | 161 DCHECK(cached_data->rejected()); |
| 173 return MaybeHandle<SharedFunctionInfo>(); | 162 return MaybeHandle<SharedFunctionInfo>(); |
| 174 } | 163 } |
| 175 | 164 |
| 176 // Prepare and register list of attached objects. | 165 Deserializer deserializer(scd.get()); |
| 166 deserializer.AddAttachedObject(source); |
| 177 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); | 167 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); |
| 178 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | |
| 179 code_stub_keys.length() + kCodeStubsBaseIndex); | |
| 180 attached_objects[kSourceObjectIndex] = source; | |
| 181 for (int i = 0; i < code_stub_keys.length(); i++) { | 168 for (int i = 0; i < code_stub_keys.length(); i++) { |
| 182 attached_objects[i + kCodeStubsBaseIndex] = | 169 deserializer.AddAttachedObject( |
| 183 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); | 170 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); |
| 184 } | 171 } |
| 185 | 172 |
| 186 Deserializer deserializer(scd.get()); | |
| 187 deserializer.SetAttachedObjects(attached_objects); | |
| 188 | |
| 189 // Deserialize. | 173 // Deserialize. |
| 190 Handle<SharedFunctionInfo> result; | 174 Handle<SharedFunctionInfo> result; |
| 191 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { | 175 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
| 192 // Deserializing may fail if the reservations cannot be fulfilled. | 176 // Deserializing may fail if the reservations cannot be fulfilled. |
| 193 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); | 177 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
| 194 return MaybeHandle<SharedFunctionInfo>(); | 178 return MaybeHandle<SharedFunctionInfo>(); |
| 195 } | 179 } |
| 196 | 180 |
| 197 if (FLAG_profile_deserialization) { | 181 if (FLAG_profile_deserialization) { |
| 198 double ms = timer.Elapsed().InMillisecondsF(); | 182 double ms = timer.Elapsed().InMillisecondsF(); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 SanityCheckResult r = scd->SanityCheck(isolate, source); | 357 SanityCheckResult r = scd->SanityCheck(isolate, source); |
| 374 if (r == CHECK_SUCCESS) return scd; | 358 if (r == CHECK_SUCCESS) return scd; |
| 375 cached_data->Reject(); | 359 cached_data->Reject(); |
| 376 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 360 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
| 377 delete scd; | 361 delete scd; |
| 378 return NULL; | 362 return NULL; |
| 379 } | 363 } |
| 380 | 364 |
| 381 } // namespace internal | 365 } // namespace internal |
| 382 } // namespace v8 | 366 } // namespace v8 |
| OLD | NEW |