blob: 163249e95576a421d165e6372616bae1cf6a70b7 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 IMPALA_CODEGEN_MCJIT_MEM_MGR_H
#define IMPALA_CODEGEN_MCJIT_MEM_MGR_H
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
namespace impala {
/// Custom memory manager. It is needed for a couple of purposes.
///
/// We use it as a way to resolve references to __dso_handle in cross-compiled IR.
/// This uses the same approach as the legacy llvm JIT to handle __dso_handle. MCJIT
/// doesn't handle those for us: see LLVM issue 18062.
/// TODO: get rid of this by purging the cross-compiled IR of references to __dso_handle,
/// which come from global variables with destructors.
///
/// We also use it to track how much memory is allocated for compiled code.
class ImpalaMCJITMemoryManager : public llvm::SectionMemoryManager {
public:
ImpalaMCJITMemoryManager() : bytes_allocated_(0), bytes_tracked_(0){}
virtual uint64_t getSymbolAddress(const std::string& name) override {
if (name == "__dso_handle") return reinterpret_cast<uint64_t>(&__dso_handle);
return SectionMemoryManager::getSymbolAddress(name);
}
virtual uint8_t* allocateCodeSection(uintptr_t size, unsigned alignment,
unsigned section_id, llvm::StringRef section_name) override {
bytes_allocated_ += size;
return llvm::SectionMemoryManager::allocateCodeSection(
size, alignment, section_id, section_name);
}
virtual uint8_t* allocateDataSection(uintptr_t size, unsigned alignment,
unsigned section_id, llvm::StringRef section_name, bool is_read_only) override {
bytes_allocated_ += size;
return llvm::SectionMemoryManager::allocateDataSection(
size, alignment, section_id, section_name, is_read_only);
}
int64_t bytes_allocated() const { return bytes_allocated_; }
int64_t bytes_tracked() const { return bytes_tracked_; }
void set_bytes_tracked(int64_t bytes_tracked) {
DCHECK_LE(bytes_tracked, bytes_allocated_);
bytes_tracked_ = bytes_tracked;
}
private:
/// Total bytes allocated for the compiled code.
int64_t bytes_allocated_;
/// Total bytes already tracked by MemTrackers. <= 'bytes_allocated_'.
/// Needed to release the correct amount from the MemTracker when done.
int64_t bytes_tracked_;
};
}
#endif