// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/snapshot/partial-deserializer.h"

#include "src/api.h"
#include "src/heap/heap-inl.h"
#include "src/snapshot/snapshot.h"

namespace v8 {
namespace internal {

MaybeHandle<Context> PartialDeserializer::DeserializeContext(
    Isolate* isolate, const SnapshotData* data, bool can_rehash,
    Handle<JSGlobalProxy> global_proxy,
    v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
  PartialDeserializer d(data);
  d.SetRehashability(can_rehash);

  MaybeHandle<Object> maybe_result =
      d.Deserialize(isolate, global_proxy, embedder_fields_deserializer);

  Handle<Object> result;
  return maybe_result.ToHandle(&result) ? Handle<Context>::cast(result)
                                        : MaybeHandle<Context>();
}

MaybeHandle<Object> PartialDeserializer::Deserialize(
    Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
    v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
  Initialize(isolate);
  if (!ReserveSpace()) V8::FatalProcessOutOfMemory("PartialDeserializer");

  AddAttachedObject(global_proxy);

  DisallowHeapAllocation no_gc;
  // Keep track of the code space start and end pointers in case new
  // code objects were unserialized
  OldSpace* code_space = isolate->heap()->code_space();
  Address start_address = code_space->top();
  Object* root;
  VisitRootPointer(Root::kPartialSnapshotCache, &root);
  DeserializeDeferredObjects();
  DeserializeEmbedderFields(embedder_fields_deserializer);

  RegisterDeserializedObjectsForBlackAllocation();

  // There's no code deserialized here. If this assert fires then that's
  // changed and logging should be added to notify the profiler et al of the
  // new code, which also has to be flushed from instruction cache.
  CHECK_EQ(start_address, code_space->top());

  if (FLAG_rehash_snapshot && can_rehash()) RehashContext(Context::cast(root));

  return Handle<Object>(root, isolate);
}

void PartialDeserializer::DeserializeEmbedderFields(
    v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
  if (!source()->HasMore() || source()->Get() != kEmbedderFieldsData) return;
  DisallowHeapAllocation no_gc;
  DisallowJavascriptExecution no_js(isolate());
  DisallowCompilation no_compile(isolate());
  DCHECK_NOT_NULL(embedder_fields_deserializer.callback);
  for (int code = source()->Get(); code != kSynchronize;
       code = source()->Get()) {
    HandleScope scope(isolate());
    int space = code & kSpaceMask;
    DCHECK(space <= kNumberOfSpaces);
    DCHECK(code - space == kNewObject);
    Handle<JSObject> obj(JSObject::cast(GetBackReferencedObject(space)),
                         isolate());
    int index = source()->GetInt();
    int size = source()->GetInt();
    // TODO(yangguo,jgruber): Turn this into a reusable shared buffer.
    byte* data = new byte[size];
    source()->CopyRaw(data, size);
    embedder_fields_deserializer.callback(v8::Utils::ToLocal(obj), index,
                                          {reinterpret_cast<char*>(data), size},
                                          embedder_fields_deserializer.data);
    delete[] data;
  }
}

void PartialDeserializer::RehashContext(Context* context) {
  DCHECK(can_rehash());
  for (const auto& array : transition_arrays()) array->Sort();
  context->global_object()->global_dictionary()->Rehash();
  SortMapDescriptors();
}

}  // namespace internal
}  // namespace v8
