11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_SNAPSHOT_CODE_SERIALIZER_H_
61cb0ef41Sopenharmony_ci#define V8_SNAPSHOT_CODE_SERIALIZER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/macros.h"
91cb0ef41Sopenharmony_ci#include "src/snapshot/serializer.h"
101cb0ef41Sopenharmony_ci#include "src/snapshot/snapshot-data.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciclass PersistentHandles;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE AlignedCachedData {
181cb0ef41Sopenharmony_ci public:
191cb0ef41Sopenharmony_ci  AlignedCachedData(const byte* data, int length);
201cb0ef41Sopenharmony_ci  ~AlignedCachedData() {
211cb0ef41Sopenharmony_ci    if (owns_data_) DeleteArray(data_);
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci  AlignedCachedData(const AlignedCachedData&) = delete;
241cb0ef41Sopenharmony_ci  AlignedCachedData& operator=(const AlignedCachedData&) = delete;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  const byte* data() const { return data_; }
271cb0ef41Sopenharmony_ci  int length() const { return length_; }
281cb0ef41Sopenharmony_ci  bool rejected() const { return rejected_; }
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  void Reject() { rejected_ = true; }
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  bool HasDataOwnership() const { return owns_data_; }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  void AcquireDataOwnership() {
351cb0ef41Sopenharmony_ci    DCHECK(!owns_data_);
361cb0ef41Sopenharmony_ci    owns_data_ = true;
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  void ReleaseDataOwnership() {
401cb0ef41Sopenharmony_ci    DCHECK(owns_data_);
411cb0ef41Sopenharmony_ci    owns_data_ = false;
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci private:
451cb0ef41Sopenharmony_ci  bool owns_data_ : 1;
461cb0ef41Sopenharmony_ci  bool rejected_ : 1;
471cb0ef41Sopenharmony_ci  const byte* data_;
481cb0ef41Sopenharmony_ci  int length_;
491cb0ef41Sopenharmony_ci};
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_cienum class SerializedCodeSanityCheckResult {
521cb0ef41Sopenharmony_ci  kSuccess = 0,
531cb0ef41Sopenharmony_ci  kMagicNumberMismatch = 1,
541cb0ef41Sopenharmony_ci  kVersionMismatch = 2,
551cb0ef41Sopenharmony_ci  kSourceMismatch = 3,
561cb0ef41Sopenharmony_ci  kFlagsMismatch = 5,
571cb0ef41Sopenharmony_ci  kChecksumMismatch = 6,
581cb0ef41Sopenharmony_ci  kInvalidHeader = 7,
591cb0ef41Sopenharmony_ci  kLengthMismatch = 8
601cb0ef41Sopenharmony_ci};
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ciclass CodeSerializer : public Serializer {
631cb0ef41Sopenharmony_ci public:
641cb0ef41Sopenharmony_ci  struct OffThreadDeserializeData {
651cb0ef41Sopenharmony_ci   private:
661cb0ef41Sopenharmony_ci    friend class CodeSerializer;
671cb0ef41Sopenharmony_ci    MaybeHandle<SharedFunctionInfo> maybe_result;
681cb0ef41Sopenharmony_ci    std::vector<Handle<Script>> scripts;
691cb0ef41Sopenharmony_ci    std::unique_ptr<PersistentHandles> persistent_handles;
701cb0ef41Sopenharmony_ci    SerializedCodeSanityCheckResult sanity_check_result;
711cb0ef41Sopenharmony_ci  };
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  CodeSerializer(const CodeSerializer&) = delete;
741cb0ef41Sopenharmony_ci  CodeSerializer& operator=(const CodeSerializer&) = delete;
751cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static ScriptCompiler::CachedData* Serialize(
761cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> info);
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  AlignedCachedData* SerializeSharedFunctionInfo(
791cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> info);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
821cb0ef41Sopenharmony_ci      Isolate* isolate, AlignedCachedData* cached_data, Handle<String> source,
831cb0ef41Sopenharmony_ci      ScriptOriginOptions origin_options);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT static OffThreadDeserializeData
861cb0ef41Sopenharmony_ci  StartDeserializeOffThread(LocalIsolate* isolate,
871cb0ef41Sopenharmony_ci                            AlignedCachedData* cached_data);
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo>
901cb0ef41Sopenharmony_ci  FinishOffThreadDeserialize(Isolate* isolate, OffThreadDeserializeData&& data,
911cb0ef41Sopenharmony_ci                             AlignedCachedData* cached_data,
921cb0ef41Sopenharmony_ci                             Handle<String> source,
931cb0ef41Sopenharmony_ci                             ScriptOriginOptions origin_options);
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  uint32_t source_hash() const { return source_hash_; }
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci protected:
981cb0ef41Sopenharmony_ci  CodeSerializer(Isolate* isolate, uint32_t source_hash);
991cb0ef41Sopenharmony_ci  ~CodeSerializer() override { OutputStatistics("CodeSerializer"); }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  virtual bool ElideObject(Object obj) { return false; }
1021cb0ef41Sopenharmony_ci  void SerializeGeneric(Handle<HeapObject> heap_object);
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci private:
1051cb0ef41Sopenharmony_ci  void SerializeObjectImpl(Handle<HeapObject> o) override;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  bool SerializeReadOnlyObject(HeapObject obj,
1081cb0ef41Sopenharmony_ci                               const DisallowGarbageCollection& no_gc);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  DISALLOW_GARBAGE_COLLECTION(no_gc_)
1111cb0ef41Sopenharmony_ci  uint32_t source_hash_;
1121cb0ef41Sopenharmony_ci};
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// Wrapper around ScriptData to provide code-serializer-specific functionality.
1151cb0ef41Sopenharmony_ciclass SerializedCodeData : public SerializedData {
1161cb0ef41Sopenharmony_ci public:
1171cb0ef41Sopenharmony_ci  // The data header consists of uint32_t-sized entries:
1181cb0ef41Sopenharmony_ci  // [0] magic number and (internally provided) external reference count
1191cb0ef41Sopenharmony_ci  // [1] version hash
1201cb0ef41Sopenharmony_ci  // [2] source hash
1211cb0ef41Sopenharmony_ci  // [3] flag hash
1221cb0ef41Sopenharmony_ci  // [4] payload length
1231cb0ef41Sopenharmony_ci  // [5] payload checksum
1241cb0ef41Sopenharmony_ci  // ...  serialized payload
1251cb0ef41Sopenharmony_ci  static const uint32_t kVersionHashOffset = kMagicNumberOffset + kUInt32Size;
1261cb0ef41Sopenharmony_ci  static const uint32_t kSourceHashOffset = kVersionHashOffset + kUInt32Size;
1271cb0ef41Sopenharmony_ci  static const uint32_t kFlagHashOffset = kSourceHashOffset + kUInt32Size;
1281cb0ef41Sopenharmony_ci  static const uint32_t kPayloadLengthOffset = kFlagHashOffset + kUInt32Size;
1291cb0ef41Sopenharmony_ci  static const uint32_t kChecksumOffset = kPayloadLengthOffset + kUInt32Size;
1301cb0ef41Sopenharmony_ci  static const uint32_t kUnalignedHeaderSize = kChecksumOffset + kUInt32Size;
1311cb0ef41Sopenharmony_ci  static const uint32_t kHeaderSize = POINTER_SIZE_ALIGN(kUnalignedHeaderSize);
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  // Used when consuming.
1341cb0ef41Sopenharmony_ci  static SerializedCodeData FromCachedData(
1351cb0ef41Sopenharmony_ci      AlignedCachedData* cached_data, uint32_t expected_source_hash,
1361cb0ef41Sopenharmony_ci      SerializedCodeSanityCheckResult* rejection_result);
1371cb0ef41Sopenharmony_ci  // For cached data which is consumed before the source is available (e.g.
1381cb0ef41Sopenharmony_ci  // off-thread).
1391cb0ef41Sopenharmony_ci  static SerializedCodeData FromCachedDataWithoutSource(
1401cb0ef41Sopenharmony_ci      AlignedCachedData* cached_data,
1411cb0ef41Sopenharmony_ci      SerializedCodeSanityCheckResult* rejection_result);
1421cb0ef41Sopenharmony_ci  // For cached data which was previously already sanity checked by
1431cb0ef41Sopenharmony_ci  // FromCachedDataWithoutSource. The rejection result from that call should be
1441cb0ef41Sopenharmony_ci  // passed into this one.
1451cb0ef41Sopenharmony_ci  static SerializedCodeData FromPartiallySanityCheckedCachedData(
1461cb0ef41Sopenharmony_ci      AlignedCachedData* cached_data, uint32_t expected_source_hash,
1471cb0ef41Sopenharmony_ci      SerializedCodeSanityCheckResult* rejection_result);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  // Used when producing.
1501cb0ef41Sopenharmony_ci  SerializedCodeData(const std::vector<byte>* payload,
1511cb0ef41Sopenharmony_ci                     const CodeSerializer* cs);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  // Return ScriptData object and relinquish ownership over it to the caller.
1541cb0ef41Sopenharmony_ci  AlignedCachedData* GetScriptData();
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  base::Vector<const byte> Payload() const;
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  static uint32_t SourceHash(Handle<String> source,
1591cb0ef41Sopenharmony_ci                             ScriptOriginOptions origin_options);
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci private:
1621cb0ef41Sopenharmony_ci  explicit SerializedCodeData(AlignedCachedData* data);
1631cb0ef41Sopenharmony_ci  SerializedCodeData(const byte* data, int size)
1641cb0ef41Sopenharmony_ci      : SerializedData(const_cast<byte*>(data), size) {}
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  base::Vector<const byte> ChecksummedContent() const {
1671cb0ef41Sopenharmony_ci    return base::Vector<const byte>(data_ + kHeaderSize, size_ - kHeaderSize);
1681cb0ef41Sopenharmony_ci  }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  SerializedCodeSanityCheckResult SanityCheck(
1711cb0ef41Sopenharmony_ci      uint32_t expected_source_hash) const;
1721cb0ef41Sopenharmony_ci  SerializedCodeSanityCheckResult SanityCheckJustSource(
1731cb0ef41Sopenharmony_ci      uint32_t expected_source_hash) const;
1741cb0ef41Sopenharmony_ci  SerializedCodeSanityCheckResult SanityCheckWithoutSource() const;
1751cb0ef41Sopenharmony_ci};
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci}  // namespace internal
1781cb0ef41Sopenharmony_ci}  // namespace v8
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci#endif  // V8_SNAPSHOT_CODE_SERIALIZER_H_
181