Use thread-local TC for codegen and relocate translations into the TC
[hiphop-php.git] / hphp / runtime / vm / jit / relocation.cpp
blob793582033f3d662e08657b5769d89cb8b4940588
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/relocation.h"
18 #include "hphp/runtime/vm/jit/relocation-arm.h"
19 #include "hphp/runtime/vm/jit/relocation-ppc64.h"
20 #include "hphp/runtime/vm/jit/relocation-x64.h"
22 #include "hphp/util/arch.h"
24 namespace HPHP { namespace jit {
26 void RelocationInfo::recordRange(TCA start, TCA end,
27 TCA destStart, TCA destEnd) {
28 m_srcRanges.emplace_back(start, end);
29 m_dstRanges.emplace_back(destStart, destEnd);
30 m_adjustedAddresses[start].second = destStart;
31 m_adjustedAddresses[end].first = destEnd;
34 void RelocationInfo::recordAddress(TCA src, TCA dest, int range) {
35 m_adjustedAddresses.emplace(src, std::make_pair(dest, dest + range));
38 TCA RelocationInfo::adjustedAddressAfter(TCA addr) const {
39 auto it = m_adjustedAddresses.find(addr);
40 if (it == m_adjustedAddresses.end()) return nullptr;
42 return it->second.second;
45 TCA RelocationInfo::adjustedAddressBefore(TCA addr) const {
46 auto it = m_adjustedAddresses.find(addr);
47 if (it == m_adjustedAddresses.end()) return nullptr;
49 return it->second.first;
52 void RelocationInfo::rewind(TCA start, TCA end) {
53 if (m_srcRanges.size() && m_srcRanges.back().first == start) {
54 assertx(m_dstRanges.size() == m_srcRanges.size());
55 assertx(m_srcRanges.back().second == end);
56 m_srcRanges.pop_back();
57 m_dstRanges.pop_back();
59 auto it = m_adjustedAddresses.lower_bound(start);
60 if (it == m_adjustedAddresses.end()) return;
62 // convenience function for erasing a m_smashableRelocations entry
63 auto eraseSmashableRelocation = [this](TCA addr) {
64 auto it = m_smashableRelocations.find(addr);
65 if (it != m_smashableRelocations.end()) m_smashableRelocations.erase(it);
68 if (it->first == start) {
69 // if it->second.first is set, start is also the end
70 // of an existing region. Don't erase it in that case
71 if (it->second.first) {
72 eraseSmashableRelocation(it->second.second);
73 it++->second.second = 0;
74 } else {
75 m_adjustedAddresses.erase(it++);
78 while (it != m_adjustedAddresses.end() && it->first < end) {
79 eraseSmashableRelocation(it->second.second);
80 m_adjustedAddresses.erase(it++);
82 if (it == m_adjustedAddresses.end()) return;
83 if (it->first == end) {
84 // Similar to start above, end could be the start of an
85 // existing region.
86 if (it->second.second) {
87 eraseSmashableRelocation(it->second.second);
88 it++->second.first = 0;
89 } else {
90 m_adjustedAddresses.erase(it++);
95 //////////////////////////////////////////////////////////////////////
98 * Wrappers.
101 void adjustForRelocation(RelocationInfo& rel) {
102 return ARCH_SWITCH_CALL(adjustForRelocation, rel);
104 void adjustForRelocation(RelocationInfo& rel, TCA srcStart, TCA srcEnd) {
105 return ARCH_SWITCH_CALL(adjustForRelocation, rel, srcStart, srcEnd);
107 void adjustCodeForRelocation(RelocationInfo& rel, CGMeta& fixups) {
108 return ARCH_SWITCH_CALL(adjustCodeForRelocation, rel, fixups);
110 void adjustMetaDataForRelocation(RelocationInfo& rel,
111 AsmInfo* asmInfo,
112 CGMeta& fixups) {
113 return ARCH_SWITCH_CALL(adjustMetaDataForRelocation, rel, asmInfo, fixups);
115 void findFixups(TCA start, TCA end, CGMeta& fixups) {
116 return ARCH_SWITCH_CALL(findFixups, start, end, fixups);
118 size_t relocate(RelocationInfo& rel,
119 CodeBlock& destBlock,
120 TCA start, TCA end,
121 CodeBlock& srcBlock,
122 CGMeta& fixups,
123 TCA* exitAddr) {
124 return ARCH_SWITCH_CALL(relocate, rel, destBlock, start, end, srcBlock,
125 fixups, exitAddr);
128 //////////////////////////////////////////////////////////////////////