/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_
#define ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_

#include <functional>
#include <inttypes.h>
#include <vector>

#include "arch/instruction_set_features.h"
#include "base/array_ref.h"
#include "base/locks.h"

namespace art HIDDEN {

class DexFile;
class Mutex;
class Thread;
struct JITCodeEntry;

// Must be called before zygote forks.
// Used to ensure that zygote's mini-debug-info can be shared with apps.
void NativeDebugInfoPreFork();

// Must be called after zygote forks.
void NativeDebugInfoPostFork();

ArrayRef<const uint8_t> GetJITCodeEntrySymFile(const JITCodeEntry*);

// Notify native tools (e.g. libunwind) that DEX file has been opened.
void AddNativeDebugInfoForDex(Thread* self, const DexFile* dexfile);

// Notify native tools (e.g. libunwind) that DEX file has been closed.
void RemoveNativeDebugInfoForDex(Thread* self, const DexFile* dexfile);

// Notify native tools (e.g. libunwind) that JIT has compiled a single new method.
// The method will make copy of the passed ELF file (to shrink it to the minimum size).
// If packing is allowed, the ELF file might be merged with others to save space
// (however, this drops all ELF sections other than symbols names and unwinding info).
void AddNativeDebugInfoForJit(const void* code_ptr,
                              const std::vector<uint8_t>& symfile,
                              bool allow_packing)
    REQUIRES_SHARED(Locks::jit_lock_);  // Might need JIT code cache to allocate memory.

// Notify native tools (e.g. libunwind) that JIT code has been garbage collected.
// The actual removal might be lazy. Removal of address that was not added is no-op.
void RemoveNativeDebugInfoForJit(const void* code_ptr);

// Merge and compress entries to save space.
void RepackNativeDebugInfoForJit()
    REQUIRES_SHARED(Locks::jit_lock_);  // Might need JIT code cache to allocate memory.

// Returns approximate memory used by debug info for JIT code.
size_t GetJitMiniDebugInfoMemUsage() REQUIRES_SHARED(Locks::jit_lock_);

// Get the lock which protects the native debug info.
// Used only in tests to unwind while the JIT thread is running.
// TODO: Unwinding should be race-free. Remove this.
EXPORT Mutex* GetNativeDebugInfoLock();

// Call given callback for every non-zygote symbol.
// The callback parameters are (address, size, name).
void ForEachNativeDebugSymbol(std::function<void(const void*, size_t, const char*)> cb);

}  // namespace art

#endif  // ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_
