// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_STUB_CODE_H_
#define RUNTIME_VM_STUB_CODE_H_

#include "vm/allocation.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/runtime_api.h"
#include "vm/compiler/stub_code_compiler.h"
#include "vm/object.h"
#include "vm/stub_code_list.h"

namespace dart {

// Forward declarations.
class Code;
class Isolate;
class ObjectPointerVisitor;
class RawCode;
class SnapshotReader;
class SnapshotWriter;

// Is it permitted for the stubs above to refer to Object::null(), which is
// allocated in the VM isolate and shared across all isolates.
// However, in cases where a simple GC-safe placeholder is needed on the stack,
// using Smi 0 instead of Object::null() is slightly more efficient, since a Smi
// does not require relocation.

// class StubCode is used to maintain the lifecycle of stubs.
class StubCode : public AllStatic {
 public:
  // Generate all stubs which are shared across all isolates, this is done
  // only once and the stub code resides in the vm_isolate heap.
  static void Init();

  static void Cleanup();
  static void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Returns true if stub code has been initialized.
  static bool HasBeenInitialized();

  // Check if specified pc is in the dart invocation stub used for
  // transitioning into dart code.
  static bool InInvocationStub(uword pc, bool is_interpreted_frame);

  // Check if the specified pc is in the jump to frame stub.
  static bool InJumpToFrameStub(uword pc);

  // Returns NULL if no stub found.
  static const char* NameOfStub(uword entry_point);

// Define the shared stub code accessors.
#define STUB_CODE_ACCESSOR(name)                                               \
  static const Code& name() { return *entries_[k##name##Index]; }              \
  static intptr_t name##Size() { return name().Size(); }
  VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR);
#undef STUB_CODE_ACCESSOR

  static RawCode* GetAllocationStubForClass(const Class& cls);

#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
  static RawCode* GetBuildMethodExtractorStub(ObjectPoolBuilder* pool);
#endif

  // Generate the stub and finalize the generated code into the stub
  // code executable area.
  static RawCode* Generate(
      const char* name,
      ObjectPoolBuilder* object_pool_builder,
      void (*GenerateStub)(compiler::Assembler* assembler));

  static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested);

  static const intptr_t kNoInstantiator = 0;
  static const intptr_t kInstantiationSizeInWords = 3;

  static const Code& EntryAt(intptr_t index) { return *entries_[index]; }
  static void EntryAtPut(intptr_t index, Code* entry) {
    ASSERT(entry->IsReadOnlyHandle());
    ASSERT(entries_[index] == nullptr);
    entries_[index] = entry;
  }
  static intptr_t NumEntries() { return kNumStubEntries; }

#if !defined(DART_PRECOMPILED_RUNTIME)
#define GENERATE_STUB(name)                                                    \
  static RawCode* BuildIsolateSpecific##name##Stub(ObjectPoolBuilder* opw) {   \
    return StubCode::Generate(                                                 \
        "_iso_stub_" #name, opw,                                               \
        compiler::StubCodeCompiler::Generate##name##Stub);                     \
  }
  VM_STUB_CODE_LIST(GENERATE_STUB);
#undef GENERATE_STUB
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

 private:
  friend class MegamorphicCacheTable;

  enum {
#define STUB_CODE_ENTRY(name) k##name##Index,
    VM_STUB_CODE_LIST(STUB_CODE_ENTRY)
#undef STUB_CODE_ENTRY
        kNumStubEntries
  };

  static Code* entries_[kNumStubEntries];
};

}  // namespace dart

#endif  // RUNTIME_VM_STUB_CODE_H_
