Index: src/snapshot/code-serializer.cc |
diff --git a/src/snapshot/code-serializer.cc b/src/snapshot/code-serializer.cc |
index 4d5ede79ac86b8ffd79e86e58aa3cfdddda83fbf..601659a1490aed7c8805c6b3f0a37b8095224559 100644 |
--- a/src/snapshot/code-serializer.cc |
+++ b/src/snapshot/code-serializer.cc |
@@ -10,6 +10,7 @@ |
#include "src/log.h" |
#include "src/macro-assembler.h" |
#include "src/snapshot/deserializer.h" |
+#include "src/snapshot/snapshot.h" |
#include "src/version.h" |
namespace v8 { |
@@ -28,23 +29,30 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate, |
} |
// Serialize code object. |
- CodeSerializer cs(isolate, *source); |
+ CodeSerializer cs(isolate, SerializedCodeData::SourceHash(source)); |
DisallowHeapAllocation no_gc; |
- Object** location = Handle<Object>::cast(info).location(); |
- cs.VisitPointer(location); |
- cs.SerializeDeferredObjects(); |
- cs.Pad(); |
- |
- SerializedCodeData data(cs.sink()->data(), &cs); |
- ScriptData* script_data = data.GetScriptData(); |
+ cs.reference_map()->AddAttachedReference(*source); |
+ ScriptData* ret = cs.Serialize(info); |
if (FLAG_profile_deserialization) { |
double ms = timer.Elapsed().InMillisecondsF(); |
- int length = script_data->length(); |
+ int length = ret->length(); |
PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); |
} |
- return script_data; |
+ return ret; |
+} |
+ |
+ScriptData* CodeSerializer::Serialize(Handle<HeapObject> obj) { |
+ DisallowHeapAllocation no_gc; |
+ |
+ VisitPointer(Handle<Object>::cast(obj).location()); |
+ SerializeDeferredObjects(); |
+ Pad(); |
+ |
+ SerializedCodeData data(sink()->data(), this); |
+ |
+ return data.GetScriptData(); |
} |
void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
@@ -84,10 +92,8 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
DCHECK(code_object->has_reloc_info_for_serialization()); |
SerializeGeneric(code_object, how_to_code, where_to_point); |
return; |
- case Code::WASM_FUNCTION: |
- case Code::WASM_TO_JS_FUNCTION: |
- case Code::JS_TO_WASM_FUNCTION: |
- UNREACHABLE(); |
+ default: |
+ return SerializeCodeObject(code_object, how_to_code, where_to_point); |
} |
UNREACHABLE(); |
} |
@@ -156,30 +162,37 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
HandleScope scope(isolate); |
- std::unique_ptr<SerializedCodeData> scd( |
- SerializedCodeData::FromCachedData(isolate, cached_data, *source)); |
- if (!scd) { |
+ SerializedCodeData::SanityCheckResult sanity_check_result = |
+ SerializedCodeData::CHECK_SUCCESS; |
+ const SerializedCodeData scd = SerializedCodeData::FromCachedData( |
+ isolate, cached_data, SerializedCodeData::SourceHash(source), |
+ &sanity_check_result); |
+ if (sanity_check_result != SerializedCodeData::CHECK_SUCCESS) { |
if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); |
DCHECK(cached_data->rejected()); |
+ source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample( |
+ sanity_check_result); |
return MaybeHandle<SharedFunctionInfo>(); |
} |
- Deserializer deserializer(scd.get()); |
+ Deserializer deserializer(&scd); |
deserializer.AddAttachedObject(source); |
- Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); |
+ Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); |
for (int i = 0; i < code_stub_keys.length(); i++) { |
deserializer.AddAttachedObject( |
CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); |
} |
// Deserialize. |
- Handle<SharedFunctionInfo> result; |
- if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
+ Handle<HeapObject> as_heap_object; |
+ if (!deserializer.DeserializeObject(isolate).ToHandle(&as_heap_object)) { |
// Deserializing may fail if the reservations cannot be fulfilled. |
if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
return MaybeHandle<SharedFunctionInfo>(); |
} |
+ Handle<SharedFunctionInfo> result = |
+ Handle<SharedFunctionInfo>::cast(as_heap_object); |
if (FLAG_profile_deserialization) { |
double ms = timer.Elapsed().InMillisecondsF(); |
int length = cached_data->length(); |
@@ -199,6 +212,40 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
return scope.CloseAndEscape(result); |
} |
+std::unique_ptr<ScriptData> WasmCompiledModuleSerializer::SerializeWasmModule( |
+ Isolate* isolate, Handle<FixedArray> compiled_module) { |
+ WasmCompiledModuleSerializer wasm_cs(isolate, 0); |
+ wasm_cs.reference_map()->AddAttachedReference(*isolate->native_context()); |
+ ScriptData* data = wasm_cs.Serialize(compiled_module); |
+ return std::unique_ptr<ScriptData>(data); |
+} |
+ |
+MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule( |
+ Isolate* isolate, ScriptData* data) { |
+ SerializedCodeData::SanityCheckResult sanity_check_result = |
+ SerializedCodeData::CHECK_SUCCESS; |
+ MaybeHandle<FixedArray> nothing; |
+ const SerializedCodeData scd = SerializedCodeData::FromCachedData( |
+ isolate, data, 0, &sanity_check_result); |
+ |
+ if (sanity_check_result != SerializedCodeData::CHECK_SUCCESS) { |
+ return nothing; |
+ } |
+ |
+ Deserializer deserializer(&scd, true); |
+ deserializer.AddAttachedObject(isolate->native_context()); |
+ |
+ Vector<const uint32_t> stub_keys = scd.CodeStubKeys(); |
+ for (int i = 0; i < stub_keys.length(); ++i) { |
+ deserializer.AddAttachedObject( |
+ CodeStub::GetCode(isolate, stub_keys[i]).ToHandleChecked()); |
+ } |
+ |
+ MaybeHandle<HeapObject> obj = deserializer.DeserializeObject(isolate); |
+ if (obj.is_null() || !obj.ToHandleChecked()->IsFixedArray()) return nothing; |
+ return Handle<FixedArray>::cast(obj.ToHandleChecked()); |
+} |
+ |
class Checksum { |
public: |
explicit Checksum(Vector<const byte> payload) { |
@@ -260,7 +307,7 @@ SerializedCodeData::SerializedCodeData(const List<byte>* payload, |
// Set header values. |
SetMagicNumber(cs->isolate()); |
SetHeaderValue(kVersionHashOffset, Version::Hash()); |
- SetHeaderValue(kSourceHashOffset, SourceHash(cs->source())); |
+ SetHeaderValue(kSourceHashOffset, cs->source_hash()); |
SetHeaderValue(kCpuFeaturesOffset, |
static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); |
SetHeaderValue(kFlagHashOffset, FlagList::Hash()); |
@@ -288,7 +335,7 @@ SerializedCodeData::SerializedCodeData(const List<byte>* payload, |
} |
SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( |
- Isolate* isolate, String* source) const { |
+ Isolate* isolate, uint32_t expected_source_hash) const { |
uint32_t magic_number = GetMagicNumber(); |
if (magic_number != ComputeMagicNumber(isolate)) return MAGIC_NUMBER_MISMATCH; |
uint32_t version_hash = GetHeaderValue(kVersionHashOffset); |
@@ -298,7 +345,7 @@ SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( |
uint32_t c1 = GetHeaderValue(kChecksum1Offset); |
uint32_t c2 = GetHeaderValue(kChecksum2Offset); |
if (version_hash != Version::Hash()) return VERSION_MISMATCH; |
- if (source_hash != SourceHash(source)) return SOURCE_MISMATCH; |
+ if (source_hash != expected_source_hash) return SOURCE_MISMATCH; |
if (cpu_features != static_cast<uint32_t>(CpuFeatures::SupportedFeatures())) { |
return CPU_FEATURES_MISMATCH; |
} |
@@ -307,7 +354,7 @@ SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( |
return CHECK_SUCCESS; |
} |
-uint32_t SerializedCodeData::SourceHash(String* source) const { |
+uint32_t SerializedCodeData::SourceHash(Handle<String> source) { |
return source->length(); |
} |
@@ -350,17 +397,17 @@ Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { |
SerializedCodeData::SerializedCodeData(ScriptData* data) |
: SerializedData(const_cast<byte*>(data->data()), data->length()) {} |
-SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate, |
- ScriptData* cached_data, |
- String* source) { |
+const SerializedCodeData SerializedCodeData::FromCachedData( |
+ Isolate* isolate, ScriptData* cached_data, uint32_t expected_source_hash, |
+ SanityCheckResult* rejection_result) { |
DisallowHeapAllocation no_gc; |
- SerializedCodeData* scd = new SerializedCodeData(cached_data); |
- SanityCheckResult r = scd->SanityCheck(isolate, source); |
- if (r == CHECK_SUCCESS) return scd; |
- cached_data->Reject(); |
- source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
- delete scd; |
- return NULL; |
+ SerializedCodeData scd(cached_data); |
+ *rejection_result = scd.SanityCheck(isolate, expected_source_hash); |
+ if (*rejection_result != CHECK_SUCCESS) { |
+ cached_data->Reject(); |
+ return SerializedCodeData(nullptr, 0); |
+ } |
+ return scd; |
} |
} // namespace internal |