[Lldb-commits] [lldb] r177364 - Refactored the expression parser so that the IR
Malea, Daniel
daniel.malea at intel.com
Thu Apr 18 14:53:42 PDT 2013
Hi Sean,
After some back-and-forth on IRC, I think there is a slight data race in
this function around m_did_jit. It's atomicity doesn't prevent it from
being read on line 254 before (another thread) writes to it on line 262.
Also, the weak_ptr::lock does not guarantee that multiple threads don't
enter the function -- can you please take a look?
I think jit_mutex_locker needs to be moved up one scope.
Thanks Carlo for spotting this one!
Cheers,
Dan
On 2013-03-18 8:10 PM, "Sean Callanan" <scallanan at apple.com> wrote:
>
>+void
>+IRExecutionUnit::GetRunnableInfo(Error &error,
>+ lldb::addr_t &func_addr,
>+ lldb::addr_t &func_end)
>+{
>+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet
>(LIBLLDB_LOG_EXPRESSIONS));
>+ lldb::ProcessSP process_sp(m_process_wp.lock());
>+
>+ func_addr = LLDB_INVALID_ADDRESS;
>+ func_end = LLDB_INVALID_ADDRESS;
>+
>+ if (!process_sp)
>+ {
>+ error.SetErrorToGenericError();
>+ error.SetErrorString("Couldn't write the JIT compiled code into
>the process because the process is invalid");
>+ return;
>+ }
>+
>+ if (m_did_jit)
>+ {
>+ func_addr = m_function_load_addr;
>+ func_end = m_function_end_load_addr;
>+
>+ return;
>+ }; // someone else may have gotten the mutex first
>+
>+ {
>+ Mutex::Locker jit_mutex_locker(m_jit_mutex);
>+
>+ if (m_did_jit)
>+ {
>+ func_addr = m_function_load_addr;
>+ func_end = m_function_end_load_addr;
>+
>+ return;
>+ }; // someone else may have gotten the mutex first
>+
>+ m_did_jit = true;
>+
>+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet
>(LIBLLDB_LOG_EXPRESSIONS));
>+
>+ std::string error_string;
>+
>+ if (log)
>+ {
>+ std::string s;
>+ llvm::raw_string_ostream oss(s);
>+
>+ m_module->print(oss, NULL);
>+
>+ oss.flush();
>+
>+ log->Printf ("Module being sent to JIT: \n%s", s.c_str());
>+ }
>+
>+ llvm::Triple triple(m_module->getTargetTriple());
>+ llvm::Function *function = m_module->getFunction
>(m_name.AsCString());
>+ llvm::Reloc::Model relocModel;
>+ llvm::CodeModel::Model codeModel;
>+
>+ if (triple.isOSBinFormatELF())
>+ {
>+ relocModel = llvm::Reloc::Static;
>+ // This will be small for 32-bit and large for 64-bit.
>+ codeModel = llvm::CodeModel::JITDefault;
>+ }
>+ else
>+ {
>+ relocModel = llvm::Reloc::PIC_;
>+ codeModel = llvm::CodeModel::Small;
>+ }
>+
>+ llvm::EngineBuilder builder(m_module_ap.get());
>+
>+ builder.setEngineKind(llvm::EngineKind::JIT)
>+ .setErrorStr(&error_string)
>+ .setRelocationModel(relocModel)
>+ .setJITMemoryManager(new MemoryManager(*this))
>+ .setOptLevel(llvm::CodeGenOpt::Less)
>+ .setAllocateGVsWithCode(true)
>+ .setCodeModel(codeModel)
>+ .setUseMCJIT(true);
>+
>+ llvm::StringRef mArch;
>+ llvm::StringRef mCPU;
>+ llvm::SmallVector<std::string, 0> mAttrs;
>+
>+ for (std::string &feature : m_cpu_features)
>+ mAttrs.push_back(feature);
>+
>+ llvm::TargetMachine *target_machine =
>builder.selectTarget(triple,
>+ mArch,
>+ mCPU,
>+
>mAttrs);
>+
>+ m_execution_engine_ap.reset(builder.create(target_machine));
>+
>+ if (!m_execution_engine_ap.get())
>+ {
>+ error.SetErrorToGenericError();
>+ error.SetErrorStringWithFormat("Couldn't JIT the function:
>%s", error_string.c_str());
>+ return;
>+ }
>+ else
>+ {
>+ m_module_ap.release(); // ownership was transferred
>+ }
>+
>+ m_execution_engine_ap->DisableLazyCompilation();
>+
>+ // We don't actually need the function pointer here, this just
>forces it to get resolved.
>+
>+ void *fun_ptr =
>m_execution_engine_ap->getPointerToFunction(function);
>+
>+ // Errors usually cause failures in the JIT, but if we're lucky
>we get here.
>+
>+ if (!function)
>+ {
>+ error.SetErrorToGenericError();
>+ error.SetErrorStringWithFormat("Couldn't find '%s' in the
>JITted module", m_name.AsCString());
>+ return;
>+ }
>+
>+ if (!fun_ptr)
>+ {
>+ error.SetErrorToGenericError();
>+ error.SetErrorStringWithFormat("'%s' was in the JITted
>module but wasn't lowered", m_name.AsCString());
>+ return;
>+ }
>+
>+ m_jitted_functions.push_back (JittedFunction(m_name.AsCString(),
>(lldb::addr_t)fun_ptr));
>+
>+ CommitAllocations(process_sp);
>+ ReportAllocations(*m_execution_engine_ap);
>+ WriteData(process_sp);
>+
>+ for (JittedFunction &jitted_function : m_jitted_functions)
>+ {
>+ jitted_function.m_remote_addr = GetRemoteAddressForLocal
>(jitted_function.m_local_addr);
>+
>+ if (!jitted_function.m_name.compare(m_name.AsCString()))
>+ {
>+ AddrRange func_range =
>GetRemoteRangeForLocal(jitted_function.m_local_addr);
>+ m_function_end_load_addr = func_range.first +
>func_range.second;
>+ m_function_load_addr = jitted_function.m_remote_addr;
>+ }
>+ }
>+
>+ if (log)
>+ {
>+ log->Printf("Code can be run in the target.");
>+
>+ StreamString disassembly_stream;
>+
>+ Error err = DisassembleFunction(disassembly_stream,
>process_sp);
>+
>+ if (!err.Success())
>+ {
>+ log->Printf("Couldn't disassemble function : %s",
>err.AsCString("unknown error"));
>+ }
>+ else
>+ {
>+ log->Printf("Function disassembly:\n%s",
>disassembly_stream.GetData());
>+ }
>+ }
>+
>+ func_addr = m_function_load_addr;
>+ func_end = m_function_end_load_addr;
>+
>+ return;
>+ }
>+}
>+
More information about the lldb-commits
mailing list